@@ -165,12 +165,6 @@ fn default_hook(info: &PanicInfo) {
165165    #[ cfg( feature = "backtrace" ) ]  
166166    use  sys_common:: backtrace; 
167167
168-     // Some platforms know that printing to stderr won't ever actually print 
169-     // anything, and if that's the case we can skip everything below. 
170-     if  stderr_prints_nothing ( )  { 
171-         return 
172-     } 
173- 
174168    // If this is a double panic, make sure that we print a backtrace 
175169    // for this panic. Otherwise only print it if logging is enabled. 
176170    #[ cfg( feature = "backtrace" ) ]  
@@ -185,9 +179,6 @@ fn default_hook(info: &PanicInfo) {
185179    } ; 
186180
187181    let  location = info. location ( ) . unwrap ( ) ;   // The current implementation always returns Some 
188-     let  file = location. file ( ) ; 
189-     let  line = location. line ( ) ; 
190-     let  col = location. column ( ) ; 
191182
192183    let  msg = match  info. payload ( ) . downcast_ref :: < & ' static  str > ( )  { 
193184        Some ( s)  => * s, 
@@ -201,8 +192,8 @@ fn default_hook(info: &PanicInfo) {
201192    let  name = thread. as_ref ( ) . and_then ( |t| t. name ( ) ) . unwrap_or ( "<unnamed>" ) ; 
202193
203194    let  write = |err :  & mut  :: io:: Write | { 
204-         let  _ = writeln ! ( err,  "thread '{}' panicked at '{}', {}:{}:{} " , 
205-                          name,  msg,  file ,  line ,  col ) ; 
195+         let  _ = writeln ! ( err,  "thread '{}' panicked at '{}', {}" , 
196+                          name,  msg,  location ) ; 
206197
207198        #[ cfg( feature = "backtrace" ) ]  
208199        { 
@@ -350,9 +341,38 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments,
350341    // panic + OOM properly anyway (see comment in begin_panic 
351342    // below). 
352343
353-     let  mut  s = String :: new ( ) ; 
354-     let  _ = s. write_fmt ( * msg) ; 
355-     rust_panic_with_hook ( & mut  PanicPayload :: new ( s) ,  Some ( msg) ,  file_line_col) 
344+     rust_panic_with_hook ( & mut  PanicPayload :: new ( msg) ,  Some ( msg) ,  file_line_col) ; 
345+ 
346+     struct  PanicPayload < ' a >  { 
347+         inner :  & ' a  fmt:: Arguments < ' a > , 
348+         string :  Option < String > , 
349+     } 
350+ 
351+     impl < ' a >  PanicPayload < ' a >  { 
352+         fn  new ( inner :  & ' a  fmt:: Arguments < ' a > )  -> PanicPayload < ' a >  { 
353+             PanicPayload  {  inner,  string :  None  } 
354+         } 
355+ 
356+         fn  fill ( & mut  self )  -> & mut  String  { 
357+             let  inner = self . inner ; 
358+             self . string . get_or_insert_with ( || { 
359+                 let  mut  s = String :: new ( ) ; 
360+                 drop ( s. write_fmt ( * inner) ) ; 
361+                 s
362+             } ) 
363+         } 
364+     } 
365+ 
366+     unsafe  impl < ' a >  BoxMeUp  for  PanicPayload < ' a >  { 
367+         fn  box_me_up ( & mut  self )  -> * mut  ( Any  + Send )  { 
368+             let  contents = mem:: replace ( self . fill ( ) ,  String :: new ( ) ) ; 
369+             Box :: into_raw ( Box :: new ( contents) ) 
370+         } 
371+ 
372+         fn  get ( & mut  self )  -> & ( Any  + Send )  { 
373+             self . fill ( ) 
374+         } 
375+     } 
356376} 
357377
358378/// This is the entry point of panicking for panic!() and assert!(). 
@@ -368,42 +388,41 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3
368388    // be performed in the parent of this thread instead of the thread that's 
369389    // panicking. 
370390
371-     rust_panic_with_hook ( & mut  PanicPayload :: new ( msg) ,  None ,  file_line_col) 
372- } 
373- 
374- struct  PanicPayload < A >  { 
375-     inner :  Option < A > , 
376- } 
391+     rust_panic_with_hook ( & mut  PanicPayload :: new ( msg) ,  None ,  file_line_col) ; 
377392
378- impl < A :  Send  + ' static >  PanicPayload < A >  { 
379-     fn  new ( inner :  A )  -> PanicPayload < A >  { 
380-         PanicPayload  {  inner :  Some ( inner)  } 
393+     struct  PanicPayload < A >  { 
394+         inner :  Option < A > , 
381395    } 
382- } 
383396
384- unsafe  impl < A :  Send  + ' static >  BoxMeUp  for  PanicPayload < A >  { 
385-     fn  box_me_up ( & mut  self )  -> * mut  ( Any  + Send )  { 
386-         let  data = match  self . inner . take ( )  { 
387-             Some ( a)  => Box :: new ( a)  as  Box < Any  + Send > , 
388-             None  => Box :: new ( ( ) ) , 
389-         } ; 
390-         Box :: into_raw ( data) 
397+     impl < A :  Send  + ' static >  PanicPayload < A >  { 
398+         fn  new ( inner :  A )  -> PanicPayload < A >  { 
399+             PanicPayload  {  inner :  Some ( inner)  } 
400+         } 
391401    } 
392402
393-     fn  get ( & self )  -> & ( Any  + Send )  { 
394-         match  self . inner  { 
395-             Some ( ref  a)  => a, 
396-             None  => & ( ) , 
403+     unsafe  impl < A :  Send  + ' static >  BoxMeUp  for  PanicPayload < A >  { 
404+         fn  box_me_up ( & mut  self )  -> * mut  ( Any  + Send )  { 
405+             let  data = match  self . inner . take ( )  { 
406+                 Some ( a)  => Box :: new ( a)  as  Box < Any  + Send > , 
407+                 None  => Box :: new ( ( ) ) , 
408+             } ; 
409+             Box :: into_raw ( data) 
410+         } 
411+ 
412+         fn  get ( & mut  self )  -> & ( Any  + Send )  { 
413+             match  self . inner  { 
414+                 Some ( ref  a)  => a, 
415+                 None  => & ( ) , 
416+             } 
397417        } 
398418    } 
399419} 
400420
401- /// Executes the primary logic for a panic, including checking for recursive 
402- /// panics and panic hooks. 
421+ /// Central point for dispatching panics. 
403422/// 
404- /// This is  the entry point or panics from libcore, formatted panics, and  
405- /// `Box<Any>`  panics. Here we'll verify that we're not panicking recursively,  
406- /// run panic hooks, and then delegate to the actual implementation of panics . 
423+ /// Executes  the primary logic for a panic, including checking for recursive  
424+ /// panics, panic hooks, and finally dispatching to the panic runtime to either  
425+ /// abort or unwind . 
407426fn  rust_panic_with_hook ( payload :  & mut  BoxMeUp , 
408427                        message :  Option < & fmt:: Arguments > , 
409428                        file_line_col :  & ( & ' static  str ,  u32 ,  u32 ) )  -> ! { 
@@ -423,15 +442,24 @@ fn rust_panic_with_hook(payload: &mut BoxMeUp,
423442    } 
424443
425444    unsafe  { 
426-         let  info = PanicInfo :: internal_constructor ( 
427-             payload. get ( ) , 
445+         let  mut  info = PanicInfo :: internal_constructor ( 
428446            message, 
429447            Location :: internal_constructor ( file,  line,  col) , 
430448        ) ; 
431449        HOOK_LOCK . read ( ) ; 
432450        match  HOOK  { 
433-             Hook :: Default  => default_hook ( & info) , 
434-             Hook :: Custom ( ptr)  => ( * ptr) ( & info) , 
451+             // Some platforms know that printing to stderr won't ever actually 
452+             // print anything, and if that's the case we can skip the default 
453+             // hook. 
454+             Hook :: Default  if  stderr_prints_nothing ( )  => { } 
455+             Hook :: Default  => { 
456+                 info. set_payload ( payload. get ( ) ) ; 
457+                 default_hook ( & info) ; 
458+             } 
459+             Hook :: Custom ( ptr)  => { 
460+                 info. set_payload ( payload. get ( ) ) ; 
461+                 ( * ptr) ( & info) ; 
462+             } 
435463        } 
436464        HOOK_LOCK . read_unlock ( ) ; 
437465    } 
@@ -460,7 +488,7 @@ pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! {
460488            Box :: into_raw ( mem:: replace ( & mut  self . 0 ,  Box :: new ( ( ) ) ) ) 
461489        } 
462490
463-         fn  get ( & self )  -> & ( Any  + Send )  { 
491+         fn  get ( & mut   self )  -> & ( Any  + Send )  { 
464492            & * self . 0 
465493        } 
466494    } 
0 commit comments