mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 21:05:02 +00:00
Handle panicking like rustc CTFE does
Instead of using `core::fmt::format` to format panic messages, which may in turn panic too and cause recursive panics and other messy things, redirect `panic_fmt` to `const_panic_fmt` like CTFE, which in turn goes to `panic_display` and does the things normally. See the tests for the full call stack.
This commit is contained in:
parent
062e1b9b81
commit
805f569adc
2 changed files with 63 additions and 8 deletions
|
@ -1356,18 +1356,36 @@ pub mod iter {
|
|||
// region:panic
|
||||
mod panic {
|
||||
pub macro panic_2021 {
|
||||
() => (
|
||||
$crate::panicking::panic("explicit panic")
|
||||
),
|
||||
($($t:tt)+) => (
|
||||
$crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
|
||||
),
|
||||
() => ({
|
||||
const fn panic_cold_explicit() -> ! {
|
||||
$crate::panicking::panic_explicit()
|
||||
}
|
||||
panic_cold_explicit();
|
||||
}),
|
||||
// Special-case the single-argument case for const_panic.
|
||||
("{}", $arg:expr $(,)?) => ({
|
||||
#[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval
|
||||
const fn panic_cold_display<T: $crate::fmt::Display>(arg: &T) -> ! {
|
||||
loop {}
|
||||
}
|
||||
panic_cold_display(&$arg);
|
||||
}),
|
||||
($($t:tt)+) => ({
|
||||
// Semicolon to prevent temporaries inside the formatting machinery from
|
||||
// being considered alive in the caller after the panic_fmt call.
|
||||
$crate::panicking::panic_fmt($crate::const_format_args!($($t)+));
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
mod panicking {
|
||||
#[lang = "panic_fmt"]
|
||||
pub const fn panic_fmt(_fmt: crate::fmt::Arguments<'_>) -> ! {
|
||||
#[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval
|
||||
pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
|
||||
panic_fmt(format_args!("{}", *x));
|
||||
}
|
||||
|
||||
#[lang = "panic_fmt"] // needed for const-evaluated panics
|
||||
pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue