Skip to content

Commit 27f0a5f

Browse files
committed
reorder panicking.rs to put main entry points at the top
1 parent ba38030 commit 27f0a5f

File tree

1 file changed

+67
-61
lines changed

1 file changed

+67
-61
lines changed

library/core/src/panicking.rs

Lines changed: 67 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,73 @@
2929
use crate::fmt;
3030
use crate::panic::{Location, PanicInfo};
3131

32+
// First we define the two main entry points that all panics go through.
33+
// In the end both are just convenience wrappers around `panic_impl`.
34+
35+
/// The entry point for panicking with a formatted message.
36+
///
37+
/// This is designed to reduce the amount of code required at the call
38+
/// site as much as possible (so that `panic!()` has as low an impact
39+
/// on (e.g.) the inlining of other functions as possible), by moving
40+
/// the actual formatting into this shared place.
41+
#[cold]
42+
// If panic_immediate_abort, inline the abort call,
43+
// otherwise avoid inlining because of it is cold path.
44+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
45+
#[cfg_attr(feature = "panic_immediate_abort", inline)]
46+
#[track_caller]
47+
#[lang = "panic_fmt"] // needed for const-evaluated panics
48+
#[rustc_do_not_const_check] // hooked by const-eval
49+
#[rustc_const_unstable(feature = "core_panic", issue = "none")]
50+
pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
51+
if cfg!(feature = "panic_immediate_abort") {
52+
super::intrinsics::abort()
53+
}
54+
55+
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
56+
// that gets resolved to the `#[panic_handler]` function.
57+
extern "Rust" {
58+
#[lang = "panic_impl"]
59+
fn panic_impl(pi: &PanicInfo<'_>) -> !;
60+
}
61+
62+
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), true);
63+
64+
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
65+
unsafe { panic_impl(&pi) }
66+
}
67+
68+
/// Like panic_fmt, but without unwinding and track_caller to reduce the impact on codesize.
69+
/// Also just works on `str`, as a `fmt::Arguments` needs more space to be passed.
70+
#[cold]
71+
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
72+
#[cfg_attr(feature = "panic_immediate_abort", inline)]
73+
#[cfg_attr(not(bootstrap), rustc_nounwind)]
74+
#[cfg_attr(bootstrap, rustc_allocator_nounwind)]
75+
pub fn panic_str_nounwind(msg: &'static str) -> ! {
76+
if cfg!(feature = "panic_immediate_abort") {
77+
super::intrinsics::abort()
78+
}
79+
80+
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
81+
// that gets resolved to the `#[panic_handler]` function.
82+
extern "Rust" {
83+
#[lang = "panic_impl"]
84+
fn panic_impl(pi: &PanicInfo<'_>) -> !;
85+
}
86+
87+
// PanicInfo with the `can_unwind` flag set to false forces an abort.
88+
let pieces = [msg];
89+
let fmt = fmt::Arguments::new_v1(&pieces, &[]);
90+
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false);
91+
92+
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
93+
unsafe { panic_impl(&pi) }
94+
}
95+
96+
// Next we define a bunch of higher-level wrappers that all bottom out in the two core functions
97+
// above.
98+
3299
/// The underlying implementation of libcore's `panic!` macro when no formatting is used.
33100
#[cold]
34101
// never inline unless panic_immediate_abort to avoid code
@@ -96,67 +163,6 @@ fn panic_no_unwind() -> ! {
96163
panic_str_nounwind("panic in a function that cannot unwind")
97164
}
98165

99-
/// Like panic_fmt, but without unwinding and track_caller to reduce the impact on codesize.
100-
/// Also just works on `str`, as a `fmt::Arguments` needs more space to be passed.
101-
#[cold]
102-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
103-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
104-
#[cfg_attr(not(bootstrap), rustc_nounwind)]
105-
#[cfg_attr(bootstrap, rustc_allocator_nounwind)]
106-
pub fn panic_str_nounwind(msg: &'static str) -> ! {
107-
if cfg!(feature = "panic_immediate_abort") {
108-
super::intrinsics::abort()
109-
}
110-
111-
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
112-
// that gets resolved to the `#[panic_handler]` function.
113-
extern "Rust" {
114-
#[lang = "panic_impl"]
115-
fn panic_impl(pi: &PanicInfo<'_>) -> !;
116-
}
117-
118-
// PanicInfo with the `can_unwind` flag set to false forces an abort.
119-
let pieces = [msg];
120-
let fmt = fmt::Arguments::new_v1(&pieces, &[]);
121-
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), false);
122-
123-
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
124-
unsafe { panic_impl(&pi) }
125-
}
126-
127-
/// The entry point for panicking with a formatted message.
128-
///
129-
/// This is designed to reduce the amount of code required at the call
130-
/// site as much as possible (so that `panic!()` has as low an impact
131-
/// on (e.g.) the inlining of other functions as possible), by moving
132-
/// the actual formatting into this shared place.
133-
#[cold]
134-
// If panic_immediate_abort, inline the abort call,
135-
// otherwise avoid inlining because of it is cold path.
136-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
137-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
138-
#[track_caller]
139-
#[lang = "panic_fmt"] // needed for const-evaluated panics
140-
#[rustc_do_not_const_check] // hooked by const-eval
141-
#[rustc_const_unstable(feature = "core_panic", issue = "none")]
142-
pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
143-
if cfg!(feature = "panic_immediate_abort") {
144-
super::intrinsics::abort()
145-
}
146-
147-
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
148-
// that gets resolved to the `#[panic_handler]` function.
149-
extern "Rust" {
150-
#[lang = "panic_impl"]
151-
fn panic_impl(pi: &PanicInfo<'_>) -> !;
152-
}
153-
154-
let pi = PanicInfo::internal_constructor(Some(&fmt), Location::caller(), true);
155-
156-
// SAFETY: `panic_impl` is defined in safe Rust code and thus is safe to call.
157-
unsafe { panic_impl(&pi) }
158-
}
159-
160166
/// This function is used instead of panic_fmt in const eval.
161167
#[lang = "const_panic_fmt"]
162168
#[rustc_const_unstable(feature = "core_panic", issue = "none")]

0 commit comments

Comments
 (0)