@@ -64,13 +64,17 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
6464 unsafe { panic_impl ( & pi) }
6565}
6666
67- /// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize.
68- /// (No `fmt` variant as a `fmt::Arguments` needs more space to be passed.)
67+ /// Like `panic_fmt`, but for non-unwinding panics.
68+ ///
69+ /// Has to be a separate function so that it can carry the `rustc_nounwind` attribute.
6970#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
7071#[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
71- #[ cfg_attr( not( bootstrap) , lang = "panic_nounwind" ) ] // needed by codegen for non-unwinding panics
72+ #[ track_caller]
73+ // This attribute has the key side-effect that if the panic handler ignores `can_unwind`
74+ // and unwinds anyway, we will hit the "unwinding out of nounwind function" guard,
75+ // which causes a "panic in a function that cannot unwind".
7276#[ rustc_nounwind]
73- pub fn panic_nounwind ( msg : & ' static str ) -> ! {
77+ pub fn panic_nounwind_fmt ( fmt : fmt :: Arguments < ' _ > ) -> ! {
7478 if cfg ! ( feature = "panic_immediate_abort" ) {
7579 super :: intrinsics:: abort ( )
7680 }
@@ -83,8 +87,6 @@ pub fn panic_nounwind(msg: &'static str) -> ! {
8387 }
8488
8589 // PanicInfo with the `can_unwind` flag set to false forces an abort.
86- let pieces = [ msg] ;
87- let fmt = fmt:: Arguments :: new_v1 ( & pieces, & [ ] ) ;
8890 let pi = PanicInfo :: internal_constructor ( Some ( & fmt) , Location :: caller ( ) , false ) ;
8991
9092 // 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) -> ! {
112114 panic_fmt ( fmt:: Arguments :: new_v1 ( & [ expr] , & [ ] ) ) ;
113115}
114116
117+ /// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize.
118+ #[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
119+ #[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
120+ #[ cfg_attr( not( bootstrap) , lang = "panic_nounwind" ) ] // needed by codegen for non-unwinding panics
121+ #[ rustc_nounwind]
122+ pub fn panic_nounwind ( expr : & ' static str ) -> ! {
123+ panic_nounwind_fmt ( fmt:: Arguments :: new_v1 ( & [ expr] , & [ ] ) ) ;
124+ }
125+
115126#[ inline]
116127#[ track_caller]
117128#[ rustc_diagnostic_item = "panic_str" ]
0 commit comments