33
44#![ allow( dead_code) ]
55
6+ use crate :: sync:: IntoDynSyncSend ;
7+ use crate :: FatalErrorMarker ;
68use parking_lot:: Mutex ;
79use std:: any:: Any ;
810use std:: panic:: { catch_unwind, resume_unwind, AssertUnwindSafe } ;
@@ -18,14 +20,17 @@ pub use enabled::*;
1820/// continuing with unwinding. It's also used for the non-parallel code to ensure error message
1921/// output match the parallel compiler for testing purposes.
2022pub struct ParallelGuard {
21- panic : Mutex < Option < Box < dyn Any + Send + ' static > > > ,
23+ panic : Mutex < Option < IntoDynSyncSend < Box < dyn Any + Send + ' static > > > > ,
2224}
2325
2426impl ParallelGuard {
2527 pub fn run < R > ( & self , f : impl FnOnce ( ) -> R ) -> Option < R > {
2628 catch_unwind ( AssertUnwindSafe ( f) )
2729 . map_err ( |err| {
28- * self . panic . lock ( ) = Some ( err) ;
30+ let mut panic = self . panic . lock ( ) ;
31+ if panic. is_none ( ) || !( * err) . is :: < FatalErrorMarker > ( ) {
32+ * panic = Some ( IntoDynSyncSend ( err) ) ;
33+ }
2934 } )
3035 . ok ( )
3136 }
@@ -37,7 +42,7 @@ impl ParallelGuard {
3742pub fn parallel_guard < R > ( f : impl FnOnce ( & ParallelGuard ) -> R ) -> R {
3843 let guard = ParallelGuard { panic : Mutex :: new ( None ) } ;
3944 let ret = f ( & guard) ;
40- if let Some ( panic) = guard. panic . into_inner ( ) {
45+ if let Some ( IntoDynSyncSend ( panic) ) = guard. panic . into_inner ( ) {
4146 resume_unwind ( panic) ;
4247 }
4348 ret
@@ -106,14 +111,20 @@ mod enabled {
106111 parallel!( impl $fblock [ $block, $( $c, ) * ] [ $( $rest) ,* ] )
107112 } ;
108113 ( impl $fblock: block [ $( $blocks: expr, ) * ] [ ] ) => {
109- :: rustc_data_structures:: sync:: scope( |s| {
110- $( let block = rustc_data_structures:: sync:: FromDyn :: from( || $blocks) ;
111- s. spawn( move |_| block. into_inner( ) ( ) ) ; ) *
112- ( || $fblock) ( ) ;
114+ $crate:: sync:: parallel_guard( |guard| {
115+ $crate:: sync:: scope( |s| {
116+ $(
117+ let block = $crate:: sync:: FromDyn :: from( || $blocks) ;
118+ s. spawn( move |_| {
119+ guard. run( move || block. into_inner( ) ( ) ) ;
120+ } ) ;
121+ ) *
122+ guard. run( || $fblock) ;
123+ } ) ;
113124 } ) ;
114125 } ;
115126 ( $fblock: block, $( $blocks: block) ,* ) => {
116- if rustc_data_structures :: sync:: is_dyn_thread_safe( ) {
127+ if $crate :: sync:: is_dyn_thread_safe( ) {
117128 // Reverse the order of the later blocks since Rayon executes them in reverse order
118129 // when using a single thread. This ensures the execution order matches that
119130 // of a single threaded rustc.
@@ -146,11 +157,13 @@ mod enabled {
146157 if mode:: is_dyn_thread_safe ( ) {
147158 let oper_a = FromDyn :: from ( oper_a) ;
148159 let oper_b = FromDyn :: from ( oper_b) ;
149- let ( a, b) = rayon:: join (
150- move || FromDyn :: from ( oper_a. into_inner ( ) ( ) ) ,
151- move || FromDyn :: from ( oper_b. into_inner ( ) ( ) ) ,
152- ) ;
153- ( a. into_inner ( ) , b. into_inner ( ) )
160+ let ( a, b) = parallel_guard ( |guard| {
161+ rayon:: join (
162+ move || guard. run ( move || FromDyn :: from ( oper_a. into_inner ( ) ( ) ) ) ,
163+ move || guard. run ( move || FromDyn :: from ( oper_b. into_inner ( ) ( ) ) ) ,
164+ )
165+ } ) ;
166+ ( a. unwrap ( ) . into_inner ( ) , b. unwrap ( ) . into_inner ( ) )
154167 } else {
155168 super :: disabled:: join ( oper_a, oper_b)
156169 }
0 commit comments