Skip to content

Commit 8a24112

Browse files
committed
Ensure panic! messages are only formatted once
1 parent 42c0fc7 commit 8a24112

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

library/std/src/panicking.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -252,20 +252,20 @@ fn default_hook(info: &PanicInfo<'_>) {
252252
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
253253

254254
let write = |err: &mut dyn crate::io::Write| {
255-
// Use the panic message directly if available, otherwise take it from
256-
// the payload.
257-
if let Some(msg) = info.message() {
258-
let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");
255+
// The std panic runtime always sets a `&str` or `String` payload for `panic!` and related
256+
// macros with the formatted message.
257+
// We try using the payload first to avoid formatting the message twice.
258+
let msg: &dyn fmt::Display = if let Some(s) = info.payload().downcast_ref::<&'static str>()
259+
{
260+
s
261+
} else if let Some(s) = info.payload().downcast_ref::<String>() {
262+
s
263+
} else if let Some(msg) = info.message() {
264+
msg
259265
} else {
260-
let msg = if let Some(s) = info.payload().downcast_ref::<&'static str>() {
261-
*s
262-
} else if let Some(s) = info.payload().downcast_ref::<String>() {
263-
&s[..]
264-
} else {
265-
"Box<dyn Any>"
266-
};
267-
let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");
268-
}
266+
&"Box<dyn Any>"
267+
};
268+
let _ = writeln!(err, "thread '{name}' panicked at {location}:\n{msg}");
269269

270270
static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
271271

0 commit comments

Comments
 (0)