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_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")]
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/// 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)]
147pub 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