1//! Panic support in the standard library.
2
3#![stable(feature = "core_panic_info", since = "1.41.0")]
4
5mod location;
6mod panic_info;
7mod unwind_safe;
8
9use crate::any::Any;
10
11#[stable(feature = "panic_hooks", since = "1.10.0")]
12pub use self::location::Location;
13#[stable(feature = "panic_hooks", since = "1.10.0")]
14pub use self::panic_info::PanicInfo;
15#[stable(feature = "catch_unwind", since = "1.9.0")]
16pub use self::unwind_safe::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};
17
18#[doc(hidden)]
19#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
20#[allow_internal_unstable(panic_internals, const_format_args)]
21#[rustc_diagnostic_item = "core_panic_2015_macro"]
22#[rustc_macro_transparency = "semitransparent"]
23pub macro panic_2015 {
24 () => (
25 $crate::panicking::panic("explicit panic")
26 ),
27 ($msg:literal $(,)?) => (
28 $crate::panicking::panic($msg)
29 ),
30 // Use `panic_str` instead of `panic_display::<&str>` for non_fmt_panic lint.
31 ($msg:expr $(,)?) => ({
32 $crate::panicking::panic_str($msg);
33 }),
34 // Special-case the single-argument case for const_panic.
35 ("{}", $arg:expr $(,)?) => ({
36 $crate::panicking::panic_display(&$arg);
37 }),
38 ($fmt:expr, $($arg:tt)+) => ({
39 // Semicolon to prevent temporaries inside the formatting machinery from
40 // being considered alive in the caller after the panic_fmt call.
41 $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+));
42 }),
43}
44
45#[doc(hidden)]
46#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
47#[allow_internal_unstable(panic_internals, const_format_args)]
48#[rustc_diagnostic_item = "core_panic_2021_macro"]
49#[rustc_macro_transparency = "semitransparent"]
50#[cfg(feature = "panic_immediate_abort")]
51pub macro panic_2021 {
52 () => (
53 $crate::panicking::panic("explicit panic")
54 ),
55 // Special-case the single-argument case for const_panic.
56 ("{}", $arg:expr $(,)?) => ({
57 $crate::panicking::panic_display(&$arg);
58 }),
59 ($($t:tt)+) => ({
60 // Semicolon to prevent temporaries inside the formatting machinery from
61 // being considered alive in the caller after the panic_fmt call.
62 $crate::panicking::panic_fmt($crate::const_format_args!($($t)+));
63 }),
64}
65
66#[doc(hidden)]
67#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
68#[allow_internal_unstable(
69 panic_internals,
70 core_intrinsics,
71 const_dispatch,
72 const_eval_select,
73 const_format_args,
74 rustc_attrs
75)]
76#[rustc_diagnostic_item = "core_panic_2021_macro"]
77#[rustc_macro_transparency = "semitransparent"]
78#[cfg(not(feature = "panic_immediate_abort"))]
79pub macro panic_2021 {
80 () => ({
81 // Create a function so that the argument for `track_caller`
82 // can be moved inside if possible.
83 #[cold]
84 #[track_caller]
85 #[inline(never)]
86 const fn panic_cold_explicit() -> ! {
87 $crate::panicking::panic_explicit()
88 }
89 panic_cold_explicit();
90 }),
91 // Special-case the single-argument case for const_panic.
92 ("{}", $arg:expr $(,)?) => ({
93 #[cold]
94 #[track_caller]
95 #[inline(never)]
96 #[rustc_const_panic_str] // enforce a &&str argument in const-check and hook this by const-eval
97 #[rustc_do_not_const_check] // hooked by const-eval
98 const fn panic_cold_display<T: $crate::fmt::Display>(arg: &T) -> ! {
99 $crate::panicking::panic_display(arg)
100 }
101 panic_cold_display(&$arg);
102 }),
103 ($($t:tt)+) => ({
104 // Semicolon to prevent temporaries inside the formatting machinery from
105 // being considered alive in the caller after the panic_fmt call.
106 $crate::panicking::panic_fmt($crate::const_format_args!($($t)+));
107 }),
108}
109
110#[doc(hidden)]
111#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")]
112#[allow_internal_unstable(panic_internals)]
113#[rustc_diagnostic_item = "unreachable_2015_macro"]
114#[rustc_macro_transparency = "semitransparent"]
115pub macro unreachable_2015 {
116 () => (
117 $crate::panicking::panic("internal error: entered unreachable code")
118 ),
119 // Use of `unreachable_display` for non_fmt_panic lint.
120 // NOTE: the message ("internal error ...") is embedded directly in unreachable_display
121 ($msg:expr $(,)?) => ({
122 $crate::panicking::unreachable_display(&$msg);
123 }),
124 ($fmt:expr, $($arg:tt)*) => (
125 $crate::panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
126 ),
127}
128
129#[doc(hidden)]
130#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")]
131#[allow_internal_unstable(panic_internals)]
132#[rustc_macro_transparency = "semitransparent"]
133pub macro unreachable_2021 {
134 () => (
135 $crate::panicking::panic("internal error: entered unreachable code")
136 ),
137 ($($t:tt)+) => (
138 $crate::panic!("internal error: entered unreachable code: {}", $crate::format_args!($($t)+))
139 ),
140}
141
142/// Asserts that a boolean expression is `true`, and perform a non-unwinding panic otherwise.
143///
144/// This macro is similar to `debug_assert!`, but is intended to be used in code that should not
145/// unwind. For example, checks in `_unchecked` functions that are intended for debugging but should
146/// not compromise unwind safety.
147#[doc(hidden)]
148#[unstable(feature = "panic_internals", issue = "none")]
149#[allow_internal_unstable(panic_internals, const_format_args)]
150#[rustc_macro_transparency = "semitransparent"]
151pub macro debug_assert_nounwind {
152 ($cond:expr $(,)?) => {
153 if $crate::cfg!(debug_assertions) {
154 if !$cond {
155 $crate::panicking::panic_nounwind($crate::concat!("assertion failed: ", $crate::stringify!($cond)));
156 }
157 }
158 },
159 ($cond:expr, $($arg:tt)+) => {
160 if $crate::cfg!(debug_assertions) {
161 if !$cond {
162 $crate::panicking::panic_nounwind_fmt($crate::const_format_args!($($arg)+), false);
163 }
164 }
165 },
166}
167
168/// An internal trait used by std to pass data from std to `panic_unwind` and
169/// other panic runtimes. Not intended to be stabilized any time soon, do not
170/// use.
171#[unstable(feature = "std_internals", issue = "none")]
172#[doc(hidden)]
173pub unsafe trait PanicPayload {
174 /// Take full ownership of the contents.
175 /// The return type is actually `Box<dyn Any + Send>`, but we cannot use `Box` in core.
176 ///
177 /// After this method got called, only some dummy default value is left in `self`.
178 /// Calling this method twice, or calling `get` after calling this method, is an error.
179 ///
180 /// The argument is borrowed because the panic runtime (`__rust_start_panic`) only
181 /// gets a borrowed `dyn PanicPayload`.
182 fn take_box(&mut self) -> *mut (dyn Any + Send);
183
184 /// Just borrow the contents.
185 fn get(&mut self) -> &(dyn Any + Send);
186}
187