@@ -186,7 +186,7 @@ fn default_hook(info: &PanicInfo) {
186186
187187 let location = info. location ( ) . unwrap ( ) ; // The current implementation always returns Some
188188
189- let msg = match info. payload ( ) . downcast_ref :: < & str > ( ) {
189+ let msg = match info. payload ( ) . downcast_ref :: < & ' static str > ( ) {
190190 Some ( s) => * s,
191191 None => match info. payload ( ) . downcast_ref :: < String > ( ) {
192192 Some ( s) => & s[ ..] ,
@@ -351,44 +351,45 @@ pub fn rust_begin_panic(info: &PanicInfo) -> ! {
351351#[ inline( never) ] #[ cold]
352352pub fn begin_panic_fmt ( msg : & fmt:: Arguments ,
353353 file_line_col : & ( & ' static str , u32 , u32 ) ) -> ! {
354- use fmt:: Write ;
355-
356354 // We do two allocations here, unfortunately. But (a) they're
357355 // required with the current scheme, and (b) we don't handle
358356 // panic + OOM properly anyway (see comment in begin_panic
359357 // below).
360358
361359 rust_panic_with_hook ( & mut PanicPayload :: new ( msg) , Some ( msg) , file_line_col) ;
360+ }
361+
362+ // NOTE(stage0) move into `continue_panic_fmt` on next stage0 update
363+ struct PanicPayload < ' a > {
364+ inner : & ' a fmt:: Arguments < ' a > ,
365+ string : Option < String > ,
366+ }
362367
363- struct PanicPayload < ' a > {
364- inner : & ' a fmt:: Arguments < ' a > ,
365- string : Option < String > ,
368+ impl < ' a > PanicPayload < ' a > {
369+ fn new ( inner : & ' a fmt:: Arguments < ' a > ) -> PanicPayload < ' a > {
370+ PanicPayload { inner , string : None }
366371 }
367372
368- impl < ' a > PanicPayload < ' a > {
369- fn new ( inner : & ' a fmt:: Arguments < ' a > ) -> PanicPayload < ' a > {
370- PanicPayload { inner, string : None }
371- }
373+ fn fill ( & mut self ) -> & mut String {
374+ use fmt:: Write ;
372375
373- fn fill ( & mut self ) -> & mut String {
374- let inner = self . inner ;
375- self . string . get_or_insert_with ( || {
376- let mut s = String :: new ( ) ;
377- drop ( s. write_fmt ( * inner) ) ;
378- s
379- } )
380- }
376+ let inner = self . inner ;
377+ self . string . get_or_insert_with ( || {
378+ let mut s = String :: new ( ) ;
379+ drop ( s. write_fmt ( * inner) ) ;
380+ s
381+ } )
381382 }
383+ }
382384
383- unsafe impl < ' a > BoxMeUp for PanicPayload < ' a > {
384- fn box_me_up ( & mut self ) -> * mut ( Any + Send ) {
385- let contents = mem:: replace ( self . fill ( ) , String :: new ( ) ) ;
386- Box :: into_raw ( Box :: new ( contents) )
387- }
385+ unsafe impl < ' a > BoxMeUp for PanicPayload < ' a > {
386+ fn box_me_up ( & mut self ) -> * mut ( Any + Send ) {
387+ let contents = mem:: replace ( self . fill ( ) , String :: new ( ) ) ;
388+ Box :: into_raw ( Box :: new ( contents) )
389+ }
388390
389- fn get ( & mut self ) -> & ( Any + Send ) {
390- self . fill ( )
391- }
391+ fn get ( & mut self ) -> & ( Any + Send ) {
392+ self . fill ( )
392393 }
393394}
394395
@@ -415,76 +416,26 @@ pub fn begin_panic_fmt(msg: &fmt::Arguments,
415416
416417#[ cfg( not( stage0) ) ]
417418fn continue_panic_fmt ( info : & PanicInfo ) -> ! {
418- use fmt:: Write ;
419-
420419 // We do two allocations here, unfortunately. But (a) they're
421420 // required with the current scheme, and (b) we don't handle
422421 // panic + OOM properly anyway (see comment in begin_panic
423422 // below).
424423
425424 let loc = info. location ( ) . unwrap ( ) ; // The current implementation always returns Some
425+ let msg = info. message ( ) . unwrap ( ) ; // The current implementation always returns Some
426426 let file_line_col = ( loc. file ( ) , loc. line ( ) , loc. column ( ) ) ;
427427 rust_panic_with_hook (
428- & mut PanicPayload :: new ( info . payload ( ) , info . message ( ) ) ,
428+ & mut PanicPayload :: new ( msg ) ,
429429 info. message ( ) ,
430430 & file_line_col) ;
431-
432- struct PanicPayload < ' a > {
433- payload : & ' a ( Any + Send ) ,
434- msg : Option < & ' a fmt:: Arguments < ' a > > ,
435- string : Option < String > ,
436- }
437-
438- impl < ' a > PanicPayload < ' a > {
439- fn new ( payload : & ' a ( Any + Send ) , msg : Option < & ' a fmt:: Arguments < ' a > > ) -> PanicPayload < ' a > {
440- PanicPayload { payload, msg, string : None }
441- }
442-
443- fn fill ( & mut self ) -> Option < & mut String > {
444- if let Some ( msg) = self . msg . cloned ( ) {
445- Some ( self . string . get_or_insert_with ( || {
446- let mut s = String :: new ( ) ;
447- drop ( s. write_fmt ( msg) ) ;
448- s
449- } ) )
450- } else {
451- None
452- }
453- }
454- }
455-
456- unsafe impl < ' a > BoxMeUp for PanicPayload < ' a > {
457- fn box_me_up ( & mut self ) -> * mut ( Any + Send ) {
458- if let Some ( string) = self . fill ( ) {
459- let contents = mem:: replace ( string, String :: new ( ) ) ;
460- Box :: into_raw ( Box :: new ( contents) )
461- } else if let Some ( s) = self . payload . downcast_ref :: < & str > ( ) {
462- Box :: into_raw ( Box :: new ( s. to_owned ( ) ) )
463- } else if let Some ( s) = self . payload . downcast_ref :: < String > ( ) {
464- Box :: into_raw ( Box :: new ( s. clone ( ) ) )
465- } else {
466- // We can't go from &(Any+Send) to Box<Any+Send> so the payload is lost here
467- struct NoPayload ;
468- Box :: into_raw ( Box :: new ( NoPayload ) )
469- }
470- }
471-
472- fn get ( & mut self ) -> & ( Any + Send ) {
473- if let Some ( s) = self . fill ( ) {
474- s
475- } else {
476- self . payload
477- }
478- }
479- }
480431}
481432
482433/// This is the entry point of panicking for panic!() and assert!().
483434#[ unstable( feature = "libstd_sys_internals" ,
484435 reason = "used by the panic! macro" ,
485436 issue = "0" ) ]
486437#[ inline( never) ] #[ cold] // avoid code bloat at the call sites as much as possible
487- pub fn begin_panic < M : Any + Send > ( msg : M , file_line_col : & ( & str , u32 , u32 ) ) -> ! {
438+ pub fn begin_panic < M : Any + Send > ( msg : M , file_line_col : & ( & ' static str , u32 , u32 ) ) -> ! {
488439 // Note that this should be the only allocation performed in this code path.
489440 // Currently this means that panic!() on OOM will invoke this code path,
490441 // but then again we're not really ready for panic on OOM anyway. If
0 commit comments