Description
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 makepanic!("{}", 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!()
.)