3
3
4
4
#![ allow( dead_code) ]
5
5
6
+ use crate :: sync:: IntoDynSyncSend ;
7
+ use crate :: FatalErrorMarker ;
6
8
use parking_lot:: Mutex ;
7
9
use std:: any:: Any ;
8
10
use std:: panic:: { catch_unwind, resume_unwind, AssertUnwindSafe } ;
@@ -18,14 +20,17 @@ pub use enabled::*;
18
20
/// continuing with unwinding. It's also used for the non-parallel code to ensure error message
19
21
/// output match the parallel compiler for testing purposes.
20
22
pub struct ParallelGuard {
21
- panic : Mutex < Option < Box < dyn Any + Send + ' static > > > ,
23
+ panic : Mutex < Option < IntoDynSyncSend < Box < dyn Any + Send + ' static > > > > ,
22
24
}
23
25
24
26
impl ParallelGuard {
25
27
pub fn run < R > ( & self , f : impl FnOnce ( ) -> R ) -> Option < R > {
26
28
catch_unwind ( AssertUnwindSafe ( f) )
27
29
. 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
+ }
29
34
} )
30
35
. ok ( )
31
36
}
@@ -37,7 +42,7 @@ impl ParallelGuard {
37
42
pub fn parallel_guard < R > ( f : impl FnOnce ( & ParallelGuard ) -> R ) -> R {
38
43
let guard = ParallelGuard { panic : Mutex :: new ( None ) } ;
39
44
let ret = f ( & guard) ;
40
- if let Some ( panic) = guard. panic . into_inner ( ) {
45
+ if let Some ( IntoDynSyncSend ( panic) ) = guard. panic . into_inner ( ) {
41
46
resume_unwind ( panic) ;
42
47
}
43
48
ret
@@ -106,14 +111,20 @@ mod enabled {
106
111
parallel!( impl $fblock [ $block, $( $c, ) * ] [ $( $rest) ,* ] )
107
112
} ;
108
113
( 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
+ } ) ;
113
124
} ) ;
114
125
} ;
115
126
( $fblock: block, $( $blocks: block) ,* ) => {
116
- if rustc_data_structures :: sync:: is_dyn_thread_safe( ) {
127
+ if $crate :: sync:: is_dyn_thread_safe( ) {
117
128
// Reverse the order of the later blocks since Rayon executes them in reverse order
118
129
// when using a single thread. This ensures the execution order matches that
119
130
// of a single threaded rustc.
@@ -146,11 +157,13 @@ mod enabled {
146
157
if mode:: is_dyn_thread_safe ( ) {
147
158
let oper_a = FromDyn :: from ( oper_a) ;
148
159
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 ( ) )
154
167
} else {
155
168
super :: disabled:: join ( oper_a, oper_b)
156
169
}
0 commit comments