@@ -84,12 +84,27 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
8484 panic ! ( "index out of bounds: the len is {len} but the index is {index}" )
8585}
8686
87- // This function is called directly by the codegen backend, and must not have
88- // any extra arguments (including those synthesized by track_caller).
87+ /// Panic because we cannot unwind out of a function.
88+ ///
89+ /// This function is called directly by the codegen backend, and must not have
90+ /// any extra arguments (including those synthesized by track_caller).
8991#[ cold]
9092#[ inline( never) ]
9193#[ lang = "panic_no_unwind" ] // needed by codegen for panic in nounwind function
94+ #[ cfg_attr( not( bootstrap) , rustc_nounwind) ]
95+ #[ cfg_attr( bootstrap, rustc_allocator_nounwind) ]
9296fn panic_no_unwind ( ) -> ! {
97+ panic_str_nounwind ( "panic in a function that cannot unwind" )
98+ }
99+
100+ /// Like panic_fmt, but without unwinding and track_caller to reduce the impact on codesize.
101+ /// Also just works on `str`, as a `fmt::Arguments` needs more space to be passed.
102+ #[ cold]
103+ #[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) ) ]
104+ #[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
105+ #[ cfg_attr( not( bootstrap) , rustc_nounwind) ]
106+ #[ cfg_attr( bootstrap, rustc_allocator_nounwind) ]
107+ pub fn panic_str_nounwind ( msg : & ' static str ) -> ! {
93108 if cfg ! ( feature = "panic_immediate_abort" ) {
94109 super :: intrinsics:: abort ( )
95110 }
@@ -102,7 +117,8 @@ fn panic_no_unwind() -> ! {
102117 }
103118
104119 // PanicInfo with the `can_unwind` flag set to false forces an abort.
105- let fmt = format_args ! ( "panic in a function that cannot unwind" ) ;
120+ let pieces = [ msg] ;
121+ let fmt = fmt:: Arguments :: new_v1 ( & pieces, & [ ] ) ;
106122 let pi = PanicInfo :: internal_constructor ( Some ( & fmt) , Location :: caller ( ) , false ) ;
107123
108124 // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
0 commit comments