@@ -130,7 +130,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
130130#[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
131131#[ track_caller]
132132#[ rustc_const_unstable( feature = "panic_internals" , issue = "none" ) ]
133- #[ lang = "panic" ] // needed by codegen for panic on overflow and other `Assert` MIR terminators
133+ #[ lang = "panic" ] // used by lints and miri for panics
134134pub const fn panic ( expr : & ' static str ) -> ! {
135135 // Use Arguments::new_const instead of format_args!("{expr}") to potentially
136136 // reduce size overhead. The format_args! macro uses str's Display trait to
@@ -141,6 +141,69 @@ pub const fn panic(expr: &'static str) -> ! {
141141 panic_fmt ( fmt:: Arguments :: new_const ( & [ expr] ) ) ;
142142}
143143
144+ // We generate functions for usage by compiler-generated assertions.
145+ //
146+ // Placing these functions in libcore means that all Rust programs can generate a jump into this
147+ // code rather than expanding to panic("...") above, which adds extra bloat to call sites (for the
148+ // constant string argument's pointer and length).
149+ //
150+ // This is especially important when this code is called often (e.g., with -Coverflow-checks) for
151+ // reducing binary size impact.
152+ macro_rules! panic_const {
153+ ( $( $lang: ident = $message: expr, ) +) => {
154+ #[ cfg( not( bootstrap) ) ]
155+ pub mod panic_const {
156+ use super :: * ;
157+
158+ $(
159+ /// This is a panic called with a message that's a result of a MIR-produced Assert.
160+ //
161+ // never inline unless panic_immediate_abort to avoid code
162+ // bloat at the call sites as much as possible
163+ #[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
164+ #[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
165+ #[ track_caller]
166+ #[ rustc_const_unstable( feature = "panic_internals" , issue = "none" ) ]
167+ #[ lang = stringify!( $lang) ]
168+ pub const fn $lang( ) -> ! {
169+ // Use Arguments::new_const instead of format_args!("{expr}") to potentially
170+ // reduce size overhead. The format_args! macro uses str's Display trait to
171+ // write expr, which calls Formatter::pad, which must accommodate string
172+ // truncation and padding (even though none is used here). Using
173+ // Arguments::new_const may allow the compiler to omit Formatter::pad from the
174+ // output binary, saving up to a few kilobytes.
175+ panic_fmt( fmt:: Arguments :: new_const( & [ $message] ) ) ;
176+ }
177+ ) +
178+ }
179+ }
180+ }
181+
182+ // Unfortunately this set of strings is replicated here and in a few places in the compiler in
183+ // slightly different forms. It's not clear if there's a good way to deduplicate without adding
184+ // special cases to the compiler (e.g., a const generic function wouldn't have a single definition
185+ // shared across crates, which is exactly what we want here).
186+ panic_const ! {
187+ panic_const_add_overflow = "attempt to add with overflow" ,
188+ panic_const_sub_overflow = "attempt to subtract with overflow" ,
189+ panic_const_mul_overflow = "attempt to multiply with overflow" ,
190+ panic_const_div_overflow = "attempt to divide with overflow" ,
191+ panic_const_rem_overflow = "attempt to calculate the remainder with overflow" ,
192+ panic_const_neg_overflow = "attempt to negate with overflow" ,
193+ panic_const_shr_overflow = "attempt to shift right with overflow" ,
194+ panic_const_shl_overflow = "attempt to shift left with overflow" ,
195+ panic_const_div_by_zero = "attempt to divide by zero" ,
196+ panic_const_rem_by_zero = "attempt to calculate the remainder with a divisor of zero" ,
197+ panic_const_coroutine_resumed = "coroutine resumed after completion" ,
198+ panic_const_async_fn_resumed = "`async fn` resumed after completion" ,
199+ panic_const_async_gen_fn_resumed = "`async gen fn` resumed after completion" ,
200+ panic_const_gen_fn_none = "`gen fn` should just keep returning `None` after completion" ,
201+ panic_const_coroutine_resumed_panic = "coroutine resumed after panicking" ,
202+ panic_const_async_fn_resumed_panic = "`async fn` resumed after panicking" ,
203+ panic_const_async_gen_fn_resumed_panic = "`async gen fn` resumed after panicking" ,
204+ panic_const_gen_fn_none_panic = "`gen fn` should just keep returning `None` after panicking" ,
205+ }
206+
144207/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize on the caller.
145208/// If you want `#[track_caller]` for nicer errors, call `panic_nounwind_fmt` directly.
146209#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
0 commit comments