panic!() with formatting arguments sometimes accepted in const · Issue #139621 · rust-lang/rust (original) (raw)
This issue is a combination of three things:
fn panic_fmt
is marked with#[rustc_do_not_const_check]
and fully relies onformat_args!()
with any arguments to not be accepted in const.- Inlining/flattening of format_args!() accidentally exposed as stable through const #139136 -
I accidentally marked this function asEdit: This is actually caused by [generic_assert] Constify methods used by the formatting system #135139const
, meaning that flattened format_args are accepted in const. This went unnoticed until two weeks ago. - We have a special case for panic!("{}", $expr) that we added at some point to make
panic!("{}", my_string)
work in const, as a workaround forpanic!(my_string)
which no longer works as of Rust 2021.
The result is pretty terrible:
const A1: () = if false { panic!("{}", "a") }; const A2: () = if false { panic!("{}", {"a"}) }; const A3: () = if false { panic!("{}", 1) }; // error! const A4: () = if false { panic!("{}", {1}) }; // error! const B1: () = if false { panic!(" {}", "a") }; const B2: () = if false { panic!(" {}", {"a"}) }; // error! const B3: () = if false { panic!(" {}", 1) }; const B4: () = if false { panic!(" {}", {1}) }; // error!
Only the four marked lines error. The others compile fine. 🙃
(The A
constants use the "{}"
special case for panic!()
and end up invoking panic_display
for which we have a special const eval check that the argument is a &str
. The B
constants end up invoking panic_fmt
(which does not have any const eval checks) and format_args!()
.)