22
22
use std:: cell:: Cell ;
23
23
use std:: fmt;
24
24
use std:: ops:: Deref ;
25
+ use std:: panic;
25
26
use std:: path:: PathBuf ;
26
27
use std:: ptr:: NonNull ;
28
+ use std:: thread;
27
29
28
30
use self :: storage:: { FromConcrete , ToConcrete , Storage } ;
29
31
@@ -580,8 +582,20 @@ thread_local! {
580
582
static CURRENT_FRONTEND : Cell <Option <NonNull <CurrentFrontend <' static >>>> = Cell :: new( None ) ;
581
583
}
582
584
583
- pub fn has_current_frontend ( ) -> bool {
584
- CURRENT_FRONTEND . with ( |p| p. get ( ) . is_some ( ) )
585
+ // Hide the default panic output within `proc_macro` expansions.
586
+ // NB. frontends can't do this because they may use a different libstd.
587
+ lazy_static ! {
588
+ static ref DEFAULT_HOOK : Box <Fn ( & panic:: PanicInfo ) + Sync + Send + ' static > = {
589
+ let hook = panic:: take_hook( ) ;
590
+ panic:: set_hook( Box :: new( panic_hook) ) ;
591
+ hook
592
+ } ;
593
+ }
594
+
595
+ fn panic_hook ( info : & panic:: PanicInfo ) {
596
+ if CURRENT_FRONTEND . with ( |p| p. get ( ) . is_none ( ) ) {
597
+ ( * DEFAULT_HOOK ) ( info)
598
+ }
585
599
}
586
600
587
601
fn with_current_frontend < F , R > ( f : F ) -> R
@@ -604,6 +618,9 @@ fn set_current_frontend<F, R>(frontend: &CurrentFrontend, f: F) -> R
604
618
}
605
619
}
606
620
621
+ // Ensure panic output hiding is set up.
622
+ :: lazy_static:: initialize ( & DEFAULT_HOOK ) ;
623
+
607
624
CURRENT_FRONTEND . with ( |p| {
608
625
let _reset = Reset { prev : p. get ( ) } ;
609
626
p. set ( NonNull :: new ( frontend as * const _ as * mut _ ) ) ;
@@ -657,8 +674,9 @@ fn erase_concrete_frontend<F, G, R>(ng: extern "C" fn() -> generation::Generatio
657
674
pub struct Expand1 {
658
675
next_generation : extern "C" fn ( ) -> generation:: Generation ,
659
676
data : * const ( ) ,
677
+ // FIXME(eddyb) achieve ABI compatibility for the `thread::Result` type.
660
678
run : unsafe extern "C" fn ( * const ( ) , & & CurrentFrontend , TokenStream )
661
- -> TokenStream ,
679
+ -> thread :: Result < TokenStream > ,
662
680
}
663
681
664
682
impl !Send for Expand1 { }
@@ -670,12 +688,15 @@ impl Expand1 {
670
688
{
671
689
unsafe extern "C" fn run < F > ( f : * const ( ) ,
672
690
frontend : & & CurrentFrontend ,
673
- input : TokenStream ) -> TokenStream
691
+ input : TokenStream )
692
+ -> thread:: Result < TokenStream >
674
693
where F : Fn ( :: TokenStream ) -> :: TokenStream
675
694
{
676
695
let f = & * ( f as * const F ) ;
677
696
set_current_frontend ( * frontend, || {
678
- f ( :: TokenStream ( input) ) . 0
697
+ panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
698
+ f ( :: TokenStream ( input) ) . 0
699
+ } ) )
679
700
} )
680
701
}
681
702
Expand1 {
@@ -685,15 +706,16 @@ impl Expand1 {
685
706
}
686
707
}
687
708
688
- pub fn run < F > ( & self , frontend : F , input : F :: TokenStream ) -> F :: TokenStream
709
+ pub fn run < F > ( & self , frontend : F , input : F :: TokenStream )
710
+ -> thread:: Result < F :: TokenStream >
689
711
where F : FrontendInterface < TokenNode = TokenNode < F > >
690
712
{
691
713
erase_concrete_frontend ( self . next_generation , frontend, |frontend, storage| {
692
714
let input = storage. from_concrete ( input) ;
693
715
let output = unsafe {
694
716
( self . run ) ( self . data , & frontend, input)
695
717
} ;
696
- storage. to_concrete ( output)
718
+ output . map ( |output| storage. to_concrete ( output) )
697
719
} )
698
720
}
699
721
}
@@ -705,8 +727,9 @@ impl Expand1 {
705
727
pub struct Expand2 {
706
728
next_generation : extern "C" fn ( ) -> generation:: Generation ,
707
729
data : * const ( ) ,
730
+ // FIXME(eddyb) achieve ABI compatibility for the `thread::Result` type.
708
731
run : unsafe extern "C" fn ( * const ( ) , & & CurrentFrontend , TokenStream , TokenStream )
709
- -> TokenStream ,
732
+ -> thread :: Result < TokenStream > ,
710
733
}
711
734
712
735
impl !Send for Expand2 { }
@@ -719,12 +742,15 @@ impl Expand2 {
719
742
unsafe extern "C" fn run < F > ( f : * const ( ) ,
720
743
frontend : & & CurrentFrontend ,
721
744
input : TokenStream ,
722
- input2 : TokenStream ) -> TokenStream
745
+ input2 : TokenStream )
746
+ -> thread:: Result < TokenStream >
723
747
where F : Fn ( :: TokenStream , :: TokenStream ) -> :: TokenStream
724
748
{
725
749
let f = & * ( f as * const F ) ;
726
750
set_current_frontend ( * frontend, || {
727
- f ( :: TokenStream ( input) , :: TokenStream ( input2) ) . 0
751
+ panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
752
+ f ( :: TokenStream ( input) , :: TokenStream ( input2) ) . 0
753
+ } ) )
728
754
} )
729
755
}
730
756
Expand2 {
@@ -735,7 +761,7 @@ impl Expand2 {
735
761
}
736
762
737
763
pub fn run < F > ( & self , frontend : F , input : F :: TokenStream , input2 : F :: TokenStream )
738
- -> F :: TokenStream
764
+ -> thread :: Result < F :: TokenStream >
739
765
where F : FrontendInterface < TokenNode = TokenNode < F > >
740
766
{
741
767
erase_concrete_frontend ( self . next_generation , frontend, |frontend, storage| {
@@ -744,7 +770,7 @@ impl Expand2 {
744
770
let output = unsafe {
745
771
( self . run ) ( self . data , & frontend, input, input2)
746
772
} ;
747
- storage. to_concrete ( output)
773
+ output . map ( |output| storage. to_concrete ( output) )
748
774
} )
749
775
}
750
776
}
0 commit comments