Skip to content

Commit fc2bc91

Browse files
committed
Auto merge of rust-lang#146317 - saethlin:panic=immediate-abort, r=nnethercote
Add panic=immediate-abort MCP: rust-lang/compiler-team#909 This adds a new panic strategy, `-Cpanic=immediate-abort`. This panic strategy essentially just codifies use of `-Zbuild-std-features=panic_immediate_abort`. This PR is intended to just set up infrastructure, and while it will change how the compiler is invoked for users of the feature, there should be no other impacts. In many parts of the compiler, `PanicStrategy::ImmediateAbort` behaves just like `PanicStrategy::Abort`, because actually most parts of the compiler just mean to ask "can this unwind?" so I've added a helper function so we can say `sess.panic_strategy().unwinds()`. The panic and unwind strategies have some level of compatibility, which mostly means that we can pre-compile the sysroot with unwinding panics then the sysroot can be linked with aborting panics later. The immediate-abort strategy is all-or-nothing, enforced by `compiler/rustc_metadata/src/dependency_format.rs` and this is tested for in `tests/ui/panic-runtime/`. We could _technically_ be more compatible with the other panic strategies, but immediately-aborting panics primarily exist for users who want to eliminate all the code size responsible for the panic runtime. I'm open to other use cases if people want to present them, but not right now. This PR is already large. `-Cpanic=immediate-abort` sets both `cfg(panic = "immediate-abort")` _and_ `cfg(panic = "abort")`. bjorn3 pointed out that people may be checking for the abort cfg to ask if panics will unwind, and also the sysroot feature this is replacing used to require `-Cpanic=abort` so this seems like a good back-compat step. At least for the moment. Unclear if this is a good idea indefinitely. I can imagine this being confusing. The changes to the standard library attributes are purely mechanical. Apart from that, I removed an `unsafe` we haven't needed for a while since the `abort` intrinsic became safe, and I've added a helpful diagnostic for people trying to use the old feature. To test that `-Cpanic=immediate-abort` conflicts with other panic strategies, I've beefed up the core-stubs infrastructure a bit. There is now a separate attribute to set flags on it. I've added a test that this produces the desired codegen, called `tests/run-make-cargo/panic-immediate-abort-codegen/` and also a separate run-make-cargo test that checks that we can build a binary.
2 parents 7173fae + 8be8ecc commit fc2bc91

File tree

19 files changed

+84
-91
lines changed

19 files changed

+84
-91
lines changed

alloc/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ compiler_builtins = { path = "../compiler-builtins/compiler-builtins", features
2222
compiler-builtins-mem = ['compiler_builtins/mem']
2323
compiler-builtins-c = ["compiler_builtins/c"]
2424
compiler-builtins-no-f16-f128 = ["compiler_builtins/no-f16-f128"]
25-
# Make panics and failed asserts immediately abort without formatting any message
26-
panic_immediate_abort = ["core/panic_immediate_abort"]
2725
# Choose algorithms that are optimized for binary size instead of runtime performance
2826
optimize_for_size = ["core/optimize_for_size"]
2927

alloc/src/alloc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,12 +408,12 @@ pub const fn handle_alloc_error(layout: Layout) -> ! {
408408
}
409409
}
410410

411-
#[cfg(not(feature = "panic_immediate_abort"))]
411+
#[cfg(not(panic = "immediate-abort"))]
412412
{
413413
core::intrinsics::const_eval_select((layout,), ct_error, rt_error)
414414
}
415415

416-
#[cfg(feature = "panic_immediate_abort")]
416+
#[cfg(panic = "immediate-abort")]
417417
ct_error(layout)
418418
}
419419

alloc/src/raw_vec/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ mod tests;
2323
// ensure that the code generation related to these panics is minimal as there's
2424
// only one location which panics rather than a bunch throughout the module.
2525
#[cfg(not(no_global_oom_handling))]
26-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
26+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
2727
#[track_caller]
2828
fn capacity_overflow() -> ! {
2929
panic!("capacity overflow");

alloc/src/vec/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,7 +2020,7 @@ impl<T, A: Allocator> Vec<T, A> {
20202020
#[stable(feature = "rust1", since = "1.0.0")]
20212021
pub fn swap_remove(&mut self, index: usize) -> T {
20222022
#[cold]
2023-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
2023+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
20242024
#[track_caller]
20252025
#[optimize(size)]
20262026
fn assert_failed(index: usize, len: usize) -> ! {
@@ -2102,7 +2102,7 @@ impl<T, A: Allocator> Vec<T, A> {
21022102
#[must_use = "if you don't need a reference to the value, use `Vec::insert` instead"]
21032103
pub fn insert_mut(&mut self, index: usize, element: T) -> &mut T {
21042104
#[cold]
2105-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
2105+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
21062106
#[track_caller]
21072107
#[optimize(size)]
21082108
fn assert_failed(index: usize, len: usize) -> ! {
@@ -2166,7 +2166,7 @@ impl<T, A: Allocator> Vec<T, A> {
21662166
#[rustc_confusables("delete", "take")]
21672167
pub fn remove(&mut self, index: usize) -> T {
21682168
#[cold]
2169-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
2169+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
21702170
#[track_caller]
21712171
#[optimize(size)]
21722172
fn assert_failed(index: usize, len: usize) -> ! {
@@ -2955,7 +2955,7 @@ impl<T, A: Allocator> Vec<T, A> {
29552955
A: Clone,
29562956
{
29572957
#[cold]
2958-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
2958+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
29592959
#[track_caller]
29602960
#[optimize(size)]
29612961
fn assert_failed(at: usize, len: usize) -> ! {

core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ test = false
1616
bench = false
1717

1818
[features]
19-
# Make panics and failed asserts immediately abort without formatting any message
19+
# Issue a compile error that says to use -Cpanic=immediate-abort
2020
panic_immediate_abort = []
2121
# Choose algorithms that are optimized for binary size instead of runtime performance
2222
optimize_for_size = []

core/src/cell.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,7 @@ impl Display for BorrowMutError {
778778
}
779779

780780
// This ensures the panicking code is outlined from `borrow_mut` for `RefCell`.
781-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
781+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
782782
#[track_caller]
783783
#[cold]
784784
const fn panic_already_borrowed(err: BorrowMutError) -> ! {
@@ -790,7 +790,7 @@ const fn panic_already_borrowed(err: BorrowMutError) -> ! {
790790
}
791791

792792
// This ensures the panicking code is outlined from `borrow` for `RefCell`.
793-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
793+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
794794
#[track_caller]
795795
#[cold]
796796
const fn panic_already_mutably_borrowed(err: BorrowError) -> ! {

core/src/num/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,8 +1387,8 @@ pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8])
13871387
radix <= 16 && digits.len() <= size_of::<T>() * 2 - is_signed_ty as usize
13881388
}
13891389

1390-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
1391-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
1390+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
1391+
#[cfg_attr(panic = "immediate-abort", inline)]
13921392
#[cold]
13931393
#[track_caller]
13941394
const fn from_ascii_radix_panic(radix: u32) -> ! {

core/src/option.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,17 +2161,17 @@ impl<T, E> Option<Result<T, E>> {
21612161
}
21622162
}
21632163

2164-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
2165-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
2164+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
2165+
#[cfg_attr(panic = "immediate-abort", inline)]
21662166
#[cold]
21672167
#[track_caller]
21682168
const fn unwrap_failed() -> ! {
21692169
panic("called `Option::unwrap()` on a `None` value")
21702170
}
21712171

21722172
// This is a separate function to reduce the code size of .expect() itself.
2173-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
2174-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
2173+
#[cfg_attr(not(panic = "immediate-abort"), inline(never))]
2174+
#[cfg_attr(panic = "immediate-abort", inline)]
21752175
#[cold]
21762176
#[track_caller]
21772177
const fn expect_failed(msg: &str) -> ! {

core/src/panicking.rs

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ use crate::intrinsics::const_eval_select;
3333
use crate::panic::{Location, PanicInfo};
3434

3535
#[cfg(feature = "panic_immediate_abort")]
36-
const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C panic=abort");
36+
compile_error!(
37+
"panic_immediate_abort is now a real panic strategy! \
38+
Enable it with the compiler flags `-Zunstable-options -Cpanic=immediate-abort`"
39+
);
3740

3841
// First we define the two main entry points that all panics go through.
3942
// In the end both are just convenience wrappers around `panic_impl`.
@@ -44,16 +47,16 @@ const _: () = assert!(cfg!(panic = "abort"), "panic_immediate_abort requires -C
4447
/// site as much as possible (so that `panic!()` has as low an impact
4548
/// on (e.g.) the inlining of other functions as possible), by moving
4649
/// the actual formatting into this shared place.
47-
// If panic_immediate_abort, inline the abort call,
50+
// If panic=immediate-abort, inline the abort call,
4851
// otherwise avoid inlining because of it is cold path.
49-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
50-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
52+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
53+
#[cfg_attr(panic = "immediate-abort", inline)]
5154
#[track_caller]
5255
#[lang = "panic_fmt"] // needed for const-evaluated panics
5356
#[rustc_do_not_const_check] // hooked by const-eval
5457
#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
5558
pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
56-
if cfg!(feature = "panic_immediate_abort") {
59+
if cfg!(panic = "immediate-abort") {
5760
super::intrinsics::abort()
5861
}
5962

@@ -78,8 +81,8 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
7881
/// Like `panic_fmt`, but for non-unwinding panics.
7982
///
8083
/// Has to be a separate function so that it can carry the `rustc_nounwind` attribute.
81-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
82-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
84+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
85+
#[cfg_attr(panic = "immediate-abort", inline)]
8386
#[track_caller]
8487
// This attribute has the key side-effect that if the panic handler ignores `can_unwind`
8588
// and unwinds anyway, we will hit the "unwinding out of nounwind function" guard,
@@ -94,7 +97,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
9497
// We don't unwind anyway at compile-time so we can call the regular `panic_fmt`.
9598
panic_fmt(fmt)
9699
} else #[track_caller] {
97-
if cfg!(feature = "panic_immediate_abort") {
100+
if cfg!(panic = "immediate-abort") {
98101
super::intrinsics::abort()
99102
}
100103

@@ -123,10 +126,10 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
123126
// above.
124127

125128
/// The underlying implementation of core's `panic!` macro when no formatting is used.
126-
// Never inline unless panic_immediate_abort to avoid code
129+
// Never inline unless panic=immediate-abort to avoid code
127130
// bloat at the call sites as much as possible.
128-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
129-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
131+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
132+
#[cfg_attr(panic = "immediate-abort", inline)]
130133
#[track_caller]
131134
#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
132135
#[lang = "panic"] // used by lints and miri for panics
@@ -158,10 +161,10 @@ macro_rules! panic_const {
158161
$(
159162
/// This is a panic called with a message that's a result of a MIR-produced Assert.
160163
//
161-
// never inline unless panic_immediate_abort to avoid code
164+
// never inline unless panic=immediate-abort to avoid code
162165
// 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)]
166+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
167+
#[cfg_attr(panic = "immediate-abort", inline)]
165168
#[track_caller]
166169
#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
167170
#[lang = stringify!($lang)]
@@ -216,8 +219,8 @@ pub mod panic_const {
216219

217220
/// Like `panic`, but without unwinding and track_caller to reduce the impact on codesize on the caller.
218221
/// If you want `#[track_caller]` for nicer errors, call `panic_nounwind_fmt` directly.
219-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
220-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
222+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
223+
#[cfg_attr(panic = "immediate-abort", inline)]
221224
#[lang = "panic_nounwind"] // needed by codegen for non-unwinding panics
222225
#[rustc_nounwind]
223226
#[rustc_const_stable_indirect] // must follow stable const rules since it is exposed to stable
@@ -226,8 +229,8 @@ pub const fn panic_nounwind(expr: &'static str) -> ! {
226229
}
227230

228231
/// Like `panic_nounwind`, but also inhibits showing a backtrace.
229-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
230-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
232+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
233+
#[cfg_attr(panic = "immediate-abort", inline)]
231234
#[rustc_nounwind]
232235
pub fn panic_nounwind_nobacktrace(expr: &'static str) -> ! {
233236
panic_nounwind_fmt(fmt::Arguments::new_const(&[expr]), /* force_no_backtrace */ true);
@@ -259,25 +262,25 @@ pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
259262
panic_fmt(format_args!("{}", *x));
260263
}
261264

262-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
263-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
265+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
266+
#[cfg_attr(panic = "immediate-abort", inline)]
264267
#[track_caller]
265268
#[lang = "panic_bounds_check"] // needed by codegen for panic on OOB array/slice access
266269
fn panic_bounds_check(index: usize, len: usize) -> ! {
267-
if cfg!(feature = "panic_immediate_abort") {
270+
if cfg!(panic = "immediate-abort") {
268271
super::intrinsics::abort()
269272
}
270273

271274
panic!("index out of bounds: the len is {len} but the index is {index}")
272275
}
273276

274-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
275-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
277+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
278+
#[cfg_attr(panic = "immediate-abort", inline)]
276279
#[track_caller]
277280
#[lang = "panic_misaligned_pointer_dereference"] // needed by codegen for panic on misaligned pointer deref
278281
#[rustc_nounwind] // `CheckAlignment` MIR pass requires this function to never unwind
279282
fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
280-
if cfg!(feature = "panic_immediate_abort") {
283+
if cfg!(panic = "immediate-abort") {
281284
super::intrinsics::abort()
282285
}
283286

@@ -289,13 +292,13 @@ fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! {
289292
)
290293
}
291294

292-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
293-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
295+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
296+
#[cfg_attr(panic = "immediate-abort", inline)]
294297
#[track_caller]
295298
#[lang = "panic_null_pointer_dereference"] // needed by codegen for panic on null pointer deref
296299
#[rustc_nounwind] // `CheckNull` MIR pass requires this function to never unwind
297300
fn panic_null_pointer_dereference() -> ! {
298-
if cfg!(feature = "panic_immediate_abort") {
301+
if cfg!(panic = "immediate-abort") {
299302
super::intrinsics::abort()
300303
}
301304

@@ -305,13 +308,13 @@ fn panic_null_pointer_dereference() -> ! {
305308
)
306309
}
307310

308-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
309-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
311+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
312+
#[cfg_attr(panic = "immediate-abort", inline)]
310313
#[track_caller]
311314
#[lang = "panic_invalid_enum_construction"] // needed by codegen for panic on invalid enum construction.
312315
#[rustc_nounwind] // `CheckEnums` MIR pass requires this function to never unwind
313316
fn panic_invalid_enum_construction(source: u128) -> ! {
314-
if cfg!(feature = "panic_immediate_abort") {
317+
if cfg!(panic = "immediate-abort") {
315318
super::intrinsics::abort()
316319
}
317320

@@ -328,8 +331,8 @@ fn panic_invalid_enum_construction(source: u128) -> ! {
328331
///
329332
/// This function is called directly by the codegen backend, and must not have
330333
/// any extra arguments (including those synthesized by track_caller).
331-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
332-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
334+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
335+
#[cfg_attr(panic = "immediate-abort", inline)]
333336
#[lang = "panic_cannot_unwind"] // needed by codegen for panic in nounwind function
334337
#[rustc_nounwind]
335338
fn panic_cannot_unwind() -> ! {
@@ -344,8 +347,8 @@ fn panic_cannot_unwind() -> ! {
344347
///
345348
/// This function is called directly by the codegen backend, and must not have
346349
/// any extra arguments (including those synthesized by track_caller).
347-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
348-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
350+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
351+
#[cfg_attr(panic = "immediate-abort", inline)]
349352
#[lang = "panic_in_cleanup"] // needed by codegen for panic in nounwind function
350353
#[rustc_nounwind]
351354
fn panic_in_cleanup() -> ! {
@@ -377,8 +380,8 @@ pub enum AssertKind {
377380
}
378381

379382
/// Internal function for `assert_eq!` and `assert_ne!` macros
380-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
381-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
383+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
384+
#[cfg_attr(panic = "immediate-abort", inline)]
382385
#[track_caller]
383386
#[doc(hidden)]
384387
pub fn assert_failed<T, U>(
@@ -395,8 +398,8 @@ where
395398
}
396399

397400
/// Internal function for `assert_match!`
398-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
399-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
401+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
402+
#[cfg_attr(panic = "immediate-abort", inline)]
400403
#[track_caller]
401404
#[doc(hidden)]
402405
pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
@@ -415,8 +418,8 @@ pub fn assert_matches_failed<T: fmt::Debug + ?Sized>(
415418
}
416419

417420
/// Non-generic version of the above functions, to avoid code bloat.
418-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold, optimize(size))]
419-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
421+
#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold, optimize(size))]
422+
#[cfg_attr(panic = "immediate-abort", inline)]
420423
#[track_caller]
421424
fn assert_failed_inner(
422425
kind: AssertKind,

core/src/result.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1847,7 +1847,7 @@ impl<T, E> Result<Result<T, E>, E> {
18471847
}
18481848

18491849
// This is a separate function to reduce the code size of the methods
1850-
#[cfg(not(feature = "panic_immediate_abort"))]
1850+
#[cfg(not(panic = "immediate-abort"))]
18511851
#[inline(never)]
18521852
#[cold]
18531853
#[track_caller]
@@ -1859,7 +1859,7 @@ fn unwrap_failed(msg: &str, error: &dyn fmt::Debug) -> ! {
18591859
// that gets immediately thrown away, since vtables don't get cleaned up
18601860
// by dead code elimination if a trait object is constructed even if it goes
18611861
// unused
1862-
#[cfg(feature = "panic_immediate_abort")]
1862+
#[cfg(panic = "immediate-abort")]
18631863
#[inline]
18641864
#[cold]
18651865
#[track_caller]

0 commit comments

Comments
 (0)