File tree 3 files changed +37
-13
lines changed
3 files changed +37
-13
lines changed Original file line number Diff line number Diff line change @@ -249,20 +249,20 @@ fn default_hook(info: &PanicInfo<'_>) {
249
249
let name = thread. as_ref ( ) . and_then ( |t| t. name ( ) ) . unwrap_or ( "<unnamed>" ) ;
250
250
251
251
let write = |err : & mut dyn crate :: io:: Write | {
252
- // Use the panic message directly if available, otherwise take it from
253
- // the payload.
254
- if let Some ( msg) = info. message ( ) {
255
- let _ = writeln ! ( err, "thread '{name}' panicked at '{msg}', {location}" ) ;
252
+ // The std panic runtime always sets a `&str` or `String` payload for `panic!` and related
253
+ // macros with the formatted message.
254
+ // We try using the payload first to avoid formatting the message twice.
255
+ let msg: & dyn fmt:: Display = if let Some ( s) = info. payload ( ) . downcast_ref :: < & ' static str > ( )
256
+ {
257
+ s
258
+ } else if let Some ( s) = info. payload ( ) . downcast_ref :: < String > ( ) {
259
+ s
260
+ } else if let Some ( msg) = info. message ( ) {
261
+ msg
256
262
} else {
257
- let msg = if let Some ( s) = info. payload ( ) . downcast_ref :: < & ' static str > ( ) {
258
- * s
259
- } else if let Some ( s) = info. payload ( ) . downcast_ref :: < String > ( ) {
260
- & s[ ..]
261
- } else {
262
- "Box<dyn Any>"
263
- } ;
264
- let _ = writeln ! ( err, "thread '{name}' panicked at '{msg}', {location}" ) ;
265
- }
263
+ & "Box<dyn Any>"
264
+ } ;
265
+ let _ = writeln ! ( err, "thread '{name}' panicked at '{msg}', {location}" ) ;
266
266
267
267
static FIRST_PANIC : AtomicBool = AtomicBool :: new ( true ) ;
268
268
Original file line number Diff line number Diff line change
1
+ // run-fail
2
+ // check-run-results
3
+ // exec-env:RUST_BACKTRACE=0
4
+
5
+ // Test that we format the panic message only once.
6
+ // Regression test for https://github.com/rust-lang/rust/issues/110717
7
+
8
+ use std:: fmt;
9
+
10
+ struct PrintOnFmt ;
11
+
12
+ impl fmt:: Display for PrintOnFmt {
13
+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
14
+ eprintln ! ( "fmt" ) ;
15
+ f. write_str ( "PrintOnFmt" )
16
+ }
17
+ }
18
+
19
+ fn main ( ) {
20
+ panic ! ( "{}" , PrintOnFmt )
21
+ }
Original file line number Diff line number Diff line change
1
+ fmt
2
+ thread 'main' panicked at 'PrintOnFmt', $DIR/fmt-only-once.rs:20:5
3
+ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
You can’t perform that action at this time.
0 commit comments