|
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