@@ -82,28 +82,41 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
82
82
// and unwinds anyway, we will hit the "unwinding out of nounwind function" guard,
83
83
// which causes a "panic in a function that cannot unwind".
84
84
#[ 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
+ }
89
91
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) }
95
109
}
96
110
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
+ }
104
115
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
+ }
107
120
}
108
121
109
122
// 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) -> ! {
132
145
#[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
133
146
#[ lang = "panic_nounwind" ] // needed by codegen for non-unwinding panics
134
147
#[ 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 ) -> ! {
136
150
panic_nounwind_fmt ( fmt:: Arguments :: new_const ( & [ expr] ) , /* force_no_backtrace */ false ) ;
137
151
}
138
152
0 commit comments