@@ -64,13 +64,17 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
64
64
unsafe { panic_impl ( & pi) }
65
65
}
66
66
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.
69
70
#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
70
71
#[ 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".
72
76
#[ rustc_nounwind]
73
- pub fn panic_nounwind ( msg : & ' static str ) -> ! {
77
+ pub fn panic_nounwind_fmt ( fmt : fmt :: Arguments < ' _ > ) -> ! {
74
78
if cfg ! ( feature = "panic_immediate_abort" ) {
75
79
super :: intrinsics:: abort ( )
76
80
}
@@ -83,8 +87,6 @@ pub fn panic_nounwind(msg: &'static str) -> ! {
83
87
}
84
88
85
89
// PanicInfo with the `can_unwind` flag set to false forces an abort.
86
- let pieces = [ msg] ;
87
- let fmt = fmt:: Arguments :: new_v1 ( & pieces, & [ ] ) ;
88
90
let pi = PanicInfo :: internal_constructor ( Some ( & fmt) , Location :: caller ( ) , false ) ;
89
91
90
92
// 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) -> ! {
112
114
panic_fmt ( fmt:: Arguments :: new_v1 ( & [ expr] , & [ ] ) ) ;
113
115
}
114
116
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
+
115
126
#[ inline]
116
127
#[ track_caller]
117
128
#[ rustc_diagnostic_item = "panic_str" ]
0 commit comments