X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=library%2Fcore%2Fsrc%2Fpanicking.rs;h=805a1e51ae9c09e6d583b295701706190e56a98d;hb=5b08c9f39754039ef9c6cbde157ac9eb8c252a58;hp=0146a3c2fbf7f02ddbc70f4c26343eb058faa5ba;hpb=442f997f98ac9f16f60ba3a7109f884dbf8d370c;p=rust.git diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 0146a3c2fbf..805a1e51ae9 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -64,13 +64,17 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! { unsafe { panic_impl(&pi) } } -/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize. -/// (No `fmt` variant as a `fmt::Arguments` needs more space to be passed.) +/// Like `panic_fmt`, but for non-unwinding panics. +/// +/// Has to be a separate function so that it can carry the `rustc_nounwind` attribute. #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] -#[cfg_attr(not(bootstrap), lang = "panic_nounwind")] // needed by codegen for non-unwinding panics +#[track_caller] +// This attribute has the key side-effect that if the panic handler ignores `can_unwind` +// and unwinds anyway, we will hit the "unwinding out of nounwind function" guard, +// which causes a "panic in a function that cannot unwind". #[rustc_nounwind] -pub fn panic_nounwind(msg: &'static str) -> ! { +pub fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>) -> ! { if cfg!(feature = "panic_immediate_abort") { super::intrinsics::abort() } @@ -83,8 +87,6 @@ pub fn panic_nounwind(msg: &'static str) -> ! { } // PanicInfo with the `can_unwind` flag set to false forces an abort. - let pieces = [msg]; - let fmt = fmt::Arguments::new_v1(&pieces, &[]); let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false); // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call. @@ -112,6 +114,15 @@ pub const fn panic(expr: &'static str) -> ! { panic_fmt(fmt::Arguments::new_v1(&[expr], &[])); } +/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize. +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] +#[cfg_attr(feature = "panic_immediate_abort", inline)] +#[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics +#[rustc_nounwind] +pub fn panic_nounwind(expr: &'static str) -> ! { + panic_nounwind_fmt(fmt::Arguments::new_v1(&[expr], &[])); +} + #[inline] #[track_caller] #[rustc_diagnostic_item = "panic_str"] @@ -154,8 +165,7 @@ fn panic_bounds_check(index: usize, len: usize) -> ! { /// any extra arguments (including those synthesized by track_caller). #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)] #[cfg_attr(feature = "panic_immediate_abort", inline)] -#[cfg_attr(bootstrap, lang = "panic_no_unwind")] // needed by codegen for panic in nounwind function -#[cfg_attr(not(bootstrap), lang = "panic_cannot_unwind")] // needed by codegen for panic in nounwind function +#[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function #[rustc_nounwind] fn panic_cannot_unwind() -> ! { panic_nounwind("panic in a function that cannot unwind")