Rust: with #![no_std] enabled, 'panic!("{{}}")' and 'panic!("{{}}",)' are different

Created on 7 Feb 2018  路  1Comment  路  Source: rust-lang/rust

Discovered while trying to implement fixes for #46241. Possible back-compat hazard for trailing comma support, but hopefully not.

libstd/macros.rs

macro_rules! panic {
    () => (/* default message */);
    ($msg:expr) => (/* use msg as literal */);
    ($fmt:expr, $($arg:tt)+) => (/* use format_args! */);
}

libcore/macros.rs

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>).~

A-macros C-bug T-libs

Most helpful comment

Crap. Found an example of the sort of back-compat hazard I was talking about.

In today's rust, the following two programs are different:

#![no_std]

fn main() {
    panic!("{{}}");  // panics with "{{}}"
}
#![no_std]

fn main() {
    panic!("{{}}",);  // panics with "{}"
}

>All comments

Crap. Found an example of the sort of back-compat hazard I was talking about.

In today's rust, the following two programs are different:

#![no_std]

fn main() {
    panic!("{{}}");  // panics with "{{}}"
}
#![no_std]

fn main() {
    panic!("{{}}",);  // panics with "{}"
}
Was this page helpful?
0 / 5 - 0 ratings