|
1 | | -use crate::any::Any; |
2 | 1 | use crate::fmt; |
3 | 2 | use crate::panic::Location; |
4 | 3 |
|
5 | 4 | /// A struct providing information about a panic. |
6 | 5 | /// |
7 | | -/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`] |
8 | | -/// function. |
| 6 | +/// A `PanicInfo` structure is passed to the panic handler defined by `#[panic_handler]`. |
9 | 7 | /// |
10 | | -/// [`set_hook`]: ../../std/panic/fn.set_hook.html |
| 8 | +/// For the type used by the panic hook mechanism in `std`, see [`std::panic::PanicHookInfo`]. |
11 | 9 | /// |
12 | | -/// # Examples |
13 | | -/// |
14 | | -/// ```should_panic |
15 | | -/// use std::panic; |
16 | | -/// |
17 | | -/// panic::set_hook(Box::new(|panic_info| { |
18 | | -/// println!("panic occurred: {panic_info}"); |
19 | | -/// })); |
20 | | -/// |
21 | | -/// panic!("critical system failure"); |
22 | | -/// ``` |
| 10 | +/// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html |
23 | 11 | #[lang = "panic_info"] |
24 | 12 | #[stable(feature = "panic_hooks", since = "1.10.0")] |
25 | 13 | #[derive(Debug)] |
26 | 14 | pub struct PanicInfo<'a> { |
27 | | - payload: &'a (dyn Any + Send), |
28 | | - message: Option<&'a fmt::Arguments<'a>>, |
| 15 | + message: fmt::Arguments<'a>, |
29 | 16 | location: &'a Location<'a>, |
30 | 17 | can_unwind: bool, |
31 | 18 | force_no_backtrace: bool, |
32 | 19 | } |
33 | 20 |
|
34 | 21 | impl<'a> PanicInfo<'a> { |
35 | | - #[unstable( |
36 | | - feature = "panic_internals", |
37 | | - reason = "internal details of the implementation of the `panic!` and related macros", |
38 | | - issue = "none" |
39 | | - )] |
40 | | - #[doc(hidden)] |
41 | 22 | #[inline] |
42 | | - pub fn internal_constructor( |
43 | | - message: Option<&'a fmt::Arguments<'a>>, |
| 23 | + pub(crate) fn new( |
| 24 | + message: fmt::Arguments<'a>, |
44 | 25 | location: &'a Location<'a>, |
45 | 26 | can_unwind: bool, |
46 | 27 | force_no_backtrace: bool, |
47 | 28 | ) -> Self { |
48 | | - struct NoPayload; |
49 | | - PanicInfo { location, message, payload: &NoPayload, can_unwind, force_no_backtrace } |
50 | | - } |
51 | | - |
52 | | - #[unstable( |
53 | | - feature = "panic_internals", |
54 | | - reason = "internal details of the implementation of the `panic!` and related macros", |
55 | | - issue = "none" |
56 | | - )] |
57 | | - #[doc(hidden)] |
58 | | - #[inline] |
59 | | - pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) { |
60 | | - self.payload = info; |
61 | | - } |
62 | | - |
63 | | - /// Returns the payload associated with the panic. |
64 | | - /// |
65 | | - /// This will commonly, but not always, be a `&'static str` or [`String`]. |
66 | | - /// |
67 | | - /// [`String`]: ../../std/string/struct.String.html |
68 | | - /// |
69 | | - /// # Examples |
70 | | - /// |
71 | | - /// ```should_panic |
72 | | - /// use std::panic; |
73 | | - /// |
74 | | - /// panic::set_hook(Box::new(|panic_info| { |
75 | | - /// if let Some(s) = panic_info.payload().downcast_ref::<&str>() { |
76 | | - /// println!("panic occurred: {s:?}"); |
77 | | - /// } else { |
78 | | - /// println!("panic occurred"); |
79 | | - /// } |
80 | | - /// })); |
81 | | - /// |
82 | | - /// panic!("Normal panic"); |
83 | | - /// ``` |
84 | | - #[must_use] |
85 | | - #[stable(feature = "panic_hooks", since = "1.10.0")] |
86 | | - pub fn payload(&self) -> &(dyn Any + Send) { |
87 | | - self.payload |
| 29 | + PanicInfo { location, message, can_unwind, force_no_backtrace } |
88 | 30 | } |
89 | 31 |
|
90 | 32 | /// If the `panic!` macro from the `core` crate (not from `std`) |
91 | 33 | /// was used with a formatting string and some additional arguments, |
92 | 34 | /// returns that message ready to be used for example with [`fmt::write`] |
93 | 35 | #[must_use] |
94 | 36 | #[unstable(feature = "panic_info_message", issue = "66745")] |
95 | | - pub fn message(&self) -> Option<&fmt::Arguments<'_>> { |
| 37 | + pub fn message(&self) -> fmt::Arguments<'_> { |
96 | 38 | self.message |
97 | 39 | } |
98 | 40 |
|
@@ -128,6 +70,24 @@ impl<'a> PanicInfo<'a> { |
128 | 70 | Some(&self.location) |
129 | 71 | } |
130 | 72 |
|
| 73 | + /// Returns the payload associated with the panic. |
| 74 | + /// |
| 75 | + /// On `core::panic::PanicInfo`, this method never returns anything useful. |
| 76 | + /// It only exists because of compatibility with [`std::panic::PanicHookInfo`], |
| 77 | + /// which used to be the same type. |
| 78 | + /// |
| 79 | + /// See [`std::panic::PanicHookInfo::payload`]. |
| 80 | + /// |
| 81 | + /// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html |
| 82 | + /// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload |
| 83 | + #[deprecated(since = "1.77.0", note = "this never returns anything useful")] |
| 84 | + #[stable(feature = "panic_hooks", since = "1.10.0")] |
| 85 | + #[allow(deprecated, deprecated_in_future)] |
| 86 | + pub fn payload(&self) -> &(dyn crate::any::Any + Send) { |
| 87 | + struct NoPayload; |
| 88 | + &NoPayload |
| 89 | + } |
| 90 | + |
131 | 91 | /// Returns whether the panic handler is allowed to unwind the stack from |
132 | 92 | /// the point where the panic occurred. |
133 | 93 | /// |
@@ -161,18 +121,8 @@ impl fmt::Display for PanicInfo<'_> { |
161 | 121 | fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
162 | 122 | formatter.write_str("panicked at ")?; |
163 | 123 | self.location.fmt(formatter)?; |
164 | | - formatter.write_str(":")?; |
165 | | - if let Some(message) = self.message { |
166 | | - formatter.write_str("\n")?; |
167 | | - formatter.write_fmt(*message)?; |
168 | | - } else if let Some(payload) = self.payload.downcast_ref::<&'static str>() { |
169 | | - formatter.write_str("\n")?; |
170 | | - formatter.write_str(payload)?; |
171 | | - } |
172 | | - // NOTE: we cannot use downcast_ref::<String>() here |
173 | | - // since String is not available in core! |
174 | | - // The payload is a String when `std::panic!` is called with multiple arguments, |
175 | | - // but in that case the message is also available. |
| 124 | + formatter.write_str(":\n")?; |
| 125 | + formatter.write_fmt(self.message)?; |
176 | 126 | Ok(()) |
177 | 127 | } |
178 | 128 | } |
0 commit comments