1 | //! Panic support in the standard library. |
2 | |
3 | #![stable (feature = "core_panic_info" , since = "1.41.0" )] |
4 | |
5 | mod location; |
6 | mod panic_info; |
7 | mod unwind_safe; |
8 | |
9 | use crate::any::Any; |
10 | |
11 | #[stable (feature = "panic_hooks" , since = "1.10.0" )] |
12 | pub use self::location::Location; |
13 | #[stable (feature = "panic_hooks" , since = "1.10.0" )] |
14 | pub use self::panic_info::PanicInfo; |
15 | #[stable (feature = "catch_unwind" , since = "1.9.0" )] |
16 | pub 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" ] |
23 | pub 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" )] |
51 | pub 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" ))] |
79 | pub 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" ] |
115 | pub 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" ] |
133 | pub 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" ] |
151 | pub 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)] |
173 | pub 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 | |