]> git.lizzy.rs Git - rust.git/blobdiff - library/core/src/panicking.rs
stage-step cfgs
[rust.git] / library / core / src / panicking.rs
index 0146a3c2fbf7f02ddbc70f4c26343eb058faa5ba..805a1e51ae9c09e6d583b295701706190e56a98d 100644 (file)
@@ -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")