@@ -82,28 +82,41 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
8282// and unwinds anyway, we will hit the "unwinding out of nounwind function" guard,
8383// which causes a "panic in a function that cannot unwind".
8484#[ rustc_nounwind]
85- pub fn panic_nounwind_fmt ( fmt : fmt:: Arguments < ' _ > , force_no_backtrace : bool ) -> ! {
86- if cfg ! ( feature = "panic_immediate_abort" ) {
87- super :: intrinsics:: abort ( )
88- }
85+ #[ rustc_const_unstable( feature = "core_panic" , issue = "none" ) ]
86+ pub const fn panic_nounwind_fmt ( fmt : fmt:: Arguments < ' _ > , force_no_backtrace : bool ) -> ! {
87+ fn runtime ( fmt : fmt:: Arguments < ' _ > , force_no_backtrace : bool ) -> ! {
88+ if cfg ! ( feature = "panic_immediate_abort" ) {
89+ super :: intrinsics:: abort ( )
90+ }
8991
90- // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
91- // that gets resolved to the `#[panic_handler]` function.
92- extern "Rust" {
93- #[ lang = "panic_impl" ]
94- fn panic_impl ( pi : & PanicInfo < ' _ > ) -> !;
92+ // NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
93+ // that gets resolved to the `#[panic_handler]` function.
94+ extern "Rust" {
95+ #[ lang = "panic_impl" ]
96+ fn panic_impl ( pi : & PanicInfo < ' _ > ) -> !;
97+ }
98+
99+ // PanicInfo with the `can_unwind` flag set to false forces an abort.
100+ let pi = PanicInfo :: internal_constructor (
101+ Some ( & fmt) ,
102+ Location :: caller ( ) ,
103+ /* can_unwind */ false ,
104+ force_no_backtrace,
105+ ) ;
106+
107+ // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
108+ unsafe { panic_impl ( & pi) }
95109 }
96110
97- // PanicInfo with the `can_unwind` flag set to false forces an abort.
98- let pi = PanicInfo :: internal_constructor (
99- Some ( & fmt) ,
100- Location :: caller ( ) ,
101- /* can_unwind */ false ,
102- force_no_backtrace,
103- ) ;
111+ #[ inline]
112+ const fn comptime ( fmt : fmt:: Arguments < ' _ > , _force_no_backtrace : bool ) -> ! {
113+ panic_fmt ( fmt) ;
114+ }
104115
105- // SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
106- unsafe { panic_impl ( & pi) }
116+ // SAFETY: const panic does not care about unwinding
117+ unsafe {
118+ super :: intrinsics:: const_eval_select ( ( fmt, force_no_backtrace) , comptime, runtime) ;
119+ }
107120}
108121
109122// Next we define a bunch of higher-level wrappers that all bottom out in the two core functions
@@ -132,7 +145,8 @@ pub const fn panic(expr: &'static str) -> ! {
132145#[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
133146#[ lang = "panic_nounwind" ] // needed by codegen for non-unwinding panics
134147#[ rustc_nounwind]
135- pub fn panic_nounwind ( expr : & ' static str ) -> ! {
148+ #[ rustc_const_unstable( feature = "core_panic" , issue = "none" ) ]
149+ pub const fn panic_nounwind ( expr : & ' static str ) -> ! {
136150 panic_nounwind_fmt ( fmt:: Arguments :: new_const ( & [ expr] ) , /* force_no_backtrace */ false ) ;
137151}
138152
0 commit comments