1
- use crate :: fmt;
1
+ use crate :: fmt:: { self , Display } ;
2
2
use crate :: panic:: Location ;
3
3
4
4
/// A struct providing information about a panic.
@@ -18,6 +18,17 @@ pub struct PanicInfo<'a> {
18
18
force_no_backtrace : bool ,
19
19
}
20
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
+ #[ unstable( feature = "panic_info_message" , issue = "66745" ) ]
28
+ pub struct PanicMessage < ' a > {
29
+ message : fmt:: Arguments < ' a > ,
30
+ }
31
+
21
32
impl < ' a > PanicInfo < ' a > {
22
33
#[ inline]
23
34
pub ( crate ) fn new (
@@ -29,12 +40,26 @@ impl<'a> PanicInfo<'a> {
29
40
PanicInfo { location, message, can_unwind, force_no_backtrace }
30
41
}
31
42
32
- /// The message that was given to the `panic!` macro,
33
- /// ready to be formatted with e.g. [`fmt::write`].
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
+ /// ```
34
59
#[ must_use]
35
60
#[ unstable( feature = "panic_info_message" , issue = "66745" ) ]
36
- pub fn message ( & self ) -> fmt :: Arguments < ' _ > {
37
- self . message
61
+ pub fn message ( & self ) -> PanicMessage < ' _ > {
62
+ PanicMessage { message : self . message }
38
63
}
39
64
40
65
/// Returns information about the location from which the panic originated,
@@ -116,7 +141,7 @@ impl<'a> PanicInfo<'a> {
116
141
}
117
142
118
143
#[ stable( feature = "panic_hook_display" , since = "1.26.0" ) ]
119
- impl fmt :: Display for PanicInfo < ' _ > {
144
+ impl Display for PanicInfo < ' _ > {
120
145
fn fmt ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
121
146
formatter. write_str ( "panicked at " ) ?;
122
147
self . location . fmt ( formatter) ?;
@@ -125,3 +150,41 @@ impl fmt::Display for PanicInfo<'_> {
125
150
Ok ( ( ) )
126
151
}
127
152
}
153
+
154
+ impl < ' a > PanicMessage < ' a > {
155
+ /// Get 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
+ #[ unstable( feature = "panic_info_message" , issue = "66745" ) ]
168
+ #[ rustc_const_unstable( feature = "const_arguments_as_str" , issue = "103900" ) ]
169
+ #[ must_use]
170
+ #[ inline]
171
+ pub const fn as_str ( & self ) -> Option < & ' static str > {
172
+ self . message . as_str ( )
173
+ }
174
+ }
175
+
176
+ #[ unstable( feature = "panic_info_message" , issue = "66745" ) ]
177
+ impl 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
+ #[ unstable( feature = "panic_info_message" , issue = "66745" ) ]
185
+ impl fmt:: Debug for PanicMessage < ' _ > {
186
+ #[ inline]
187
+ fn fmt ( & self , formatter : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
188
+ formatter. write_fmt ( self . message )
189
+ }
190
+ }
0 commit comments