Closed
Description
Discovered while trying to implement fixes for #46241. Possible back-compat hazard for trailing comma support, but hopefully not.
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! */);
}
Can you spot the difference?
The definition in std fails to support trailing commas after a single string literal:
fn main() {
panic!("a");
panic!("a",); //~ ERROR unexpected end of macro invocation
panic!("{}");
panic!("{}",); //~ ERROR unexpected end of macro invocation
}
The definition in core accepts a trailing comma, but follows a completely different code-path with potentially different semantics.
#![no_std]
fn main() {
panic!("a");
panic!("a",);
panic!("{}");
panic!("{}",); //~ ERROR 1 positional argument in format string, but no arguments were given
}
Fortuitously, it seems to me that it libcore's definition produces equivalent behavior for panic!(<literal>,)
and panic!(<literal>)
in all cases where both forms successfully compile, meaning it should hopefully be safe to change panic!(<literal>,)
to behave like panic!(<literal>)
.