@@ -311,47 +311,58 @@ cfg_if! {
311
311
312
312
use std;
313
313
use std:: thread;
314
- pub use rayon:: { join, scope} ;
314
+
315
+ pub use self :: serial_join as join;
316
+ pub use self :: serial_scope as scope;
315
317
316
- /// Runs a list of blocks in parallel. The first block is executed immediately on
317
- /// the current thread. Use that for the longest running block.
318
318
#[ macro_export]
319
319
macro_rules! parallel {
320
- ( impl $fblock : tt [ $ ( $c : tt, ) * ] [ $block : tt $ ( , $rest : tt ) * ] ) => {
321
- parallel! ( impl $fblock [ $block , $ ( $c , ) * ] [ $ ( $rest ) , * ] )
322
- } ;
323
- ( impl $fblock : tt [ $ ( $blocks : tt , ) * ] [ ] ) => {
324
- :: rustc_data_structures :: sync :: scope ( |s| {
325
- $ (
326
- s . spawn ( |_ | $blocks) ;
327
- ) *
328
- $fblock ;
329
- } )
330
- } ;
331
- ( $fblock : tt , $ ( $blocks : tt ) , * ) => {
332
- // Reverse the order of the later blocks since Rayon executes them in reverse order
333
- // when using a single thread. This ensures the execution order matches that
334
- // of a single threaded rustc
335
- parallel! ( impl $fblock [ ] [ $ ( $blocks ) , * ] ) ;
336
- } ;
320
+ ( $ ( $blocks : tt) , * ) => {
321
+ // We catch panics here ensuring that all the blocks execute.
322
+ // This makes behavior consistent with the parallel compiler.
323
+ let mut panic = None ;
324
+ $ (
325
+ if let Err ( p ) = :: std :: panic :: catch_unwind (
326
+ :: std :: panic :: AssertUnwindSafe ( | | $blocks)
327
+ ) {
328
+ if panic . is_none ( ) {
329
+ panic = Some ( p ) ;
330
+ }
331
+ }
332
+ ) *
333
+ if let Some ( panic ) = panic {
334
+ :: std :: panic :: resume_unwind ( panic ) ;
335
+ }
336
+ }
337
337
}
338
338
339
339
pub use rayon_core:: WorkerLocal ;
340
+ use std:: panic:: { resume_unwind, catch_unwind, AssertUnwindSafe } ;
340
341
341
- pub use rayon:: iter:: ParallelIterator ;
342
- use rayon:: iter:: IntoParallelIterator ;
342
+ pub use std:: iter:: Iterator as ParallelIterator ;
343
343
344
- pub fn par_iter<T : IntoParallelIterator >( t: T ) -> T :: Iter {
345
- t. into_par_iter ( )
344
+ pub fn par_iter<T : IntoIterator >( t: T ) -> T :: IntoIter {
345
+ t. into_iter ( )
346
346
}
347
347
348
- pub fn par_for_each_in<T : IntoParallelIterator >(
348
+ pub fn par_for_each_in<T : IntoIterator >(
349
349
t: T ,
350
- for_each: impl Fn (
351
- <<T as IntoParallelIterator >:: Iter as ParallelIterator >:: Item
352
- ) + Sync + Send
350
+ for_each:
351
+ impl Fn ( <<T as IntoIterator >:: IntoIter as Iterator >:: Item ) + Sync + Send
353
352
) {
354
- t. into_par_iter( ) . for_each( for_each)
353
+ // We catch panics here ensuring that all the loop iterations execute.
354
+ // This makes behavior consistent with the parallel compiler.
355
+ let mut panic = None ;
356
+ t. into_iter( ) . for_each( |i| {
357
+ if let Err ( p) = catch_unwind( AssertUnwindSafe ( || for_each( i) ) ) {
358
+ if panic. is_none( ) {
359
+ panic = Some ( p) ;
360
+ }
361
+ }
362
+ } ) ;
363
+ if let Some ( panic) = panic {
364
+ resume_unwind( panic) ;
365
+ }
355
366
}
356
367
357
368
pub type MetadataRef = OwningRef <Box <dyn Erased + Send + Sync >, [ u8 ] >;
0 commit comments