core/panic/
panic_info.rs

1use crate::fmt::{self, Display};
2use crate::panic::Location;
3
4/// A struct providing information about a panic.
5///
6/// A `PanicInfo` structure is passed to the panic handler defined by `#[panic_handler]`.
7///
8/// For the type used by the panic hook mechanism in `std`, see [`std::panic::PanicHookInfo`].
9///
10/// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html
11#[lang = "panic_info"]
12#[stable(feature = "panic_hooks", since = "1.10.0")]
13#[derive(Debug)]
14pub struct PanicInfo<'a> {
15    message: &'a fmt::Arguments<'a>,
16    location: &'a Location<'a>,
17    can_unwind: bool,
18    force_no_backtrace: bool,
19}
20
21/// A message that was given to the `panic!()` macro.
22///
23/// The [`Display`] implementation of this type will format the message with the arguments
24/// that were given to the `panic!()` macro.
25///
26/// See [`PanicInfo::message`].
27#[stable(feature = "panic_info_message", since = "1.81.0")]
28pub struct PanicMessage<'a> {
29    message: &'a fmt::Arguments<'a>,
30}
31
32impl<'a> PanicInfo<'a> {
33    #[inline]
34    pub(crate) fn new(
35        message: &'a fmt::Arguments<'a>,
36        location: &'a Location<'a>,
37        can_unwind: bool,
38        force_no_backtrace: bool,
39    ) -> Self {
40        PanicInfo { location, message, can_unwind, force_no_backtrace }
41    }
42
43    /// The message that was given to the `panic!` macro.
44    ///
45    /// # Example
46    ///
47    /// The type returned by this method implements `Display`, so it can
48    /// be passed directly to [`write!()`] and similar macros.
49    ///
50    /// [`write!()`]: core::write
51    ///
52    /// ```ignore (no_std)
53    /// #[panic_handler]
54    /// fn panic_handler(panic_info: &PanicInfo<'_>) -> ! {
55    ///     write!(DEBUG_OUTPUT, "panicked: {}", panic_info.message());
56    ///     loop {}
57    /// }
58    /// ```
59    #[must_use]
60    #[stable(feature = "panic_info_message", since = "1.81.0")]
61    pub fn message(&self) -> PanicMessage<'_> {
62        PanicMessage { message: self.message }
63    }
64
65    /// Returns information about the location from which the panic originated,
66    /// if available.
67    ///
68    /// This method will currently always return [`Some`], but this may change
69    /// in future versions.
70    ///
71    /// # Examples
72    ///
73    /// ```should_panic
74    /// use std::panic;
75    ///
76    /// panic::set_hook(Box::new(|panic_info| {
77    ///     if let Some(location) = panic_info.location() {
78    ///         println!("panic occurred in file '{}' at line {}",
79    ///             location.file(),
80    ///             location.line(),
81    ///         );
82    ///     } else {
83    ///         println!("panic occurred but can't get location information...");
84    ///     }
85    /// }));
86    ///
87    /// panic!("Normal panic");
88    /// ```
89    #[must_use]
90    #[stable(feature = "panic_hooks", since = "1.10.0")]
91    pub fn location(&self) -> Option<&Location<'_>> {
92        // NOTE: If this is changed to sometimes return None,
93        // deal with that case in std::panicking::default_hook and core::panicking::panic_fmt.
94        Some(&self.location)
95    }
96
97    /// Returns the payload associated with the panic.
98    ///
99    /// On this type, `core::panic::PanicInfo`, this method never returns anything useful.
100    /// It only exists because of compatibility with [`std::panic::PanicHookInfo`],
101    /// which used to be the same type.
102    ///
103    /// See [`std::panic::PanicHookInfo::payload`].
104    ///
105    /// [`std::panic::PanicHookInfo`]: ../../std/panic/struct.PanicHookInfo.html
106    /// [`std::panic::PanicHookInfo::payload`]: ../../std/panic/struct.PanicHookInfo.html#method.payload
107    #[deprecated(since = "1.81.0", note = "this never returns anything useful")]
108    #[stable(feature = "panic_hooks", since = "1.10.0")]
109    #[allow(deprecated, deprecated_in_future)]
110    pub fn payload(&self) -> &(dyn crate::any::Any + Send) {
111        struct NoPayload;
112        &NoPayload
113    }
114
115    /// Returns whether the panic handler is allowed to unwind the stack from
116    /// the point where the panic occurred.
117    ///
118    /// This is true for most kinds of panics with the exception of panics
119    /// caused by trying to unwind out of a `Drop` implementation or a function
120    /// whose ABI does not support unwinding.
121    ///
122    /// It is safe for a panic handler to unwind even when this function returns
123    /// false, however this will simply cause the panic handler to be called
124    /// again.
125    #[must_use]
126    #[unstable(feature = "panic_can_unwind", issue = "92988")]
127    pub fn can_unwind(&self) -> bool {
128        self.can_unwind
129    }
130
131    #[unstable(
132        feature = "panic_internals",
133        reason = "internal details of the implementation of the `panic!` and related macros",
134        issue = "none"
135    )]
136    #[doc(hidden)]
137    #[inline]
138    pub fn force_no_backtrace(&self) -> bool {
139        self.force_no_backtrace
140    }
141}
142
143#[stable(feature = "panic_hook_display", since = "1.26.0")]
144impl Display for PanicInfo<'_> {
145    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
146        formatter.write_str("panicked at ")?;
147        self.location.fmt(formatter)?;
148        formatter.write_str(":\n")?;
149        formatter.write_fmt(*self.message)?;
150        Ok(())
151    }
152}
153
154impl<'a> PanicMessage<'a> {
155    /// Gets the formatted message, if it has no arguments to be formatted at runtime.
156    ///
157    /// This can be used to avoid allocations in some cases.
158    ///
159    /// # Guarantees
160    ///
161    /// For `panic!("just a literal")`, this function is guaranteed to
162    /// return `Some("just a literal")`.
163    ///
164    /// For most cases with placeholders, this function will return `None`.
165    ///
166    /// See [`fmt::Arguments::as_str`] for details.
167    #[stable(feature = "panic_info_message", since = "1.81.0")]
168    #[rustc_const_stable(feature = "const_arguments_as_str", since = "1.84.0")]
169    #[must_use]
170    #[inline]
171    pub const fn as_str(&self) -> Option<&'static str> {
172        self.message.as_str()
173    }
174}
175
176#[stable(feature = "panic_info_message", since = "1.81.0")]
177impl Display for PanicMessage<'_> {
178    #[inline]
179    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
180        formatter.write_fmt(*self.message)
181    }
182}
183
184#[stable(feature = "panic_info_message", since = "1.81.0")]
185impl fmt::Debug for PanicMessage<'_> {
186    #[inline]
187    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
188        formatter.write_fmt(*self.message)
189    }
190}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy