在尝试实施针对#46241的修复程序时发现。 尾随逗号支持可能会产生反兼容性危害,但希望不会。
macro_rules! panic {
() => (/* default message */);
($msg:expr) => (/* use msg as literal */);
($fmt:expr, $($arg:tt)+) => (/* use format_args! */);
}
macro_rules! panic {
() => (/* default message */);
($msg:expr) => (/* use msg as literal */);
($fmt:expr, $($arg:tt)*) => (/* use format_args! */);
}
您看得出来差别吗?
在单个字符串文字之后,std中的定义不支持尾随逗号:
fn main() {
panic!("a");
panic!("a",); //~ ERROR unexpected end of macro invocation
panic!("{}");
panic!("{}",); //~ ERROR unexpected end of macro invocation
}
核心中的定义接受尾随逗号,但遵循具有完全不同语义的完全不同的代码路径。
#![no_std]
fn main() {
panic!("a");
panic!("a",);
panic!("{}");
panic!("{}",); //~ ERROR 1 positional argument in format string, but no arguments were given
}
〜幸运的是,在我看来,libcore的定义在两种形式都成功编译的所有情况panic!(<literal>,)
和panic!(<literal>)
产生了等效的行为,这意味着希望可以安全地更改panic!(<literal>,)
表现得像panic!(<literal>)
。〜
废话找到了我正在谈论的那种反向兼容危害的例子。
在今天的情况下,以下两个程序是不同的:
#![no_std]
fn main() {
panic!("{{}}"); // panics with "{{}}"
}
#![no_std]
fn main() {
panic!("{{}}",); // panics with "{}"
}
最有用的评论
废话找到了我正在谈论的那种反向兼容危害的例子。
在今天的情况下,以下两个程序是不同的: