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_2015` instead of `panic_display::<&str>` for non_fmt_panic lint. |
31 | ($msg:expr $(,)?) => ({ |
32 | $crate::panicking::panic_str_2015($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 | /// An internal trait used by std to pass data from std to `panic_unwind` and |
143 | /// other panic runtimes. Not intended to be stabilized any time soon, do not |
144 | /// use. |
145 | #[unstable (feature = "std_internals" , issue = "none" )] |
146 | #[doc (hidden)] |
147 | pub unsafe trait PanicPayload { |
148 | /// Take full ownership of the contents. |
149 | /// The return type is actually `Box<dyn Any + Send>`, but we cannot use `Box` in core. |
150 | /// |
151 | /// After this method got called, only some dummy default value is left in `self`. |
152 | /// Calling this method twice, or calling `get` after calling this method, is an error. |
153 | /// |
154 | /// The argument is borrowed because the panic runtime (`__rust_start_panic`) only |
155 | /// gets a borrowed `dyn PanicPayload`. |
156 | fn take_box(&mut self) -> *mut (dyn Any + Send); |
157 | |
158 | /// Just borrow the contents. |
159 | fn get(&mut self) -> &(dyn Any + Send); |
160 | } |
161 | |