diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index eb629dc44c156..3744746f1531a 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1233,7 +1233,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, "prints the llvm optimization passes being run"), ast_json: bool = (false, parse_bool, [UNTRACKED], "print the AST as JSON and halt"), - threads: Option = (None, parse_opt_uint, [UNTRACKED], + threads: Option = (Some(1), parse_opt_uint, [UNTRACKED], "use a thread pool with N threads"), ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED], "print the pre-expansion AST as JSON and halt"), diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 73247c1469efd..7bc6f7b360b8e 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -311,47 +311,58 @@ cfg_if! { use std; use std::thread; - pub use rayon::{join, scope}; + + pub use self::serial_join as join; + pub use self::serial_scope as scope; - /// Runs a list of blocks in parallel. The first block is executed immediately on - /// the current thread. Use that for the longest running block. #[macro_export] macro_rules! parallel { - (impl $fblock:tt [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => { - parallel!(impl $fblock [$block, $($c,)*] [$($rest),*]) - }; - (impl $fblock:tt [$($blocks:tt,)*] []) => { - ::rustc_data_structures::sync::scope(|s| { - $( - s.spawn(|_| $blocks); - )* - $fblock; - }) - }; - ($fblock:tt, $($blocks:tt),*) => { - // Reverse the order of the later blocks since Rayon executes them in reverse order - // when using a single thread. This ensures the execution order matches that - // of a single threaded rustc - parallel!(impl $fblock [] [$($blocks),*]); - }; + ($($blocks:tt),*) => { + // We catch panics here ensuring that all the blocks execute. + // This makes behavior consistent with the parallel compiler. + let mut panic = None; + $( + if let Err(p) = ::std::panic::catch_unwind( + ::std::panic::AssertUnwindSafe(|| $blocks) + ) { + if panic.is_none() { + panic = Some(p); + } + } + )* + if let Some(panic) = panic { + ::std::panic::resume_unwind(panic); + } + } } pub use rayon_core::WorkerLocal; + use std::panic::{resume_unwind, catch_unwind, AssertUnwindSafe}; - pub use rayon::iter::ParallelIterator; - use rayon::iter::IntoParallelIterator; + pub use std::iter::Iterator as ParallelIterator; - pub fn par_iter(t: T) -> T::Iter { - t.into_par_iter() + pub fn par_iter(t: T) -> T::IntoIter { + t.into_iter() } - pub fn par_for_each_in( + pub fn par_for_each_in( t: T, - for_each: impl Fn( - <::Iter as ParallelIterator>::Item - ) + Sync + Send + for_each: + impl Fn(<::IntoIter as Iterator>::Item) + Sync + Send ) { - t.into_par_iter().for_each(for_each) + // We catch panics here ensuring that all the loop iterations execute. + // This makes behavior consistent with the parallel compiler. + let mut panic = None; + t.into_iter().for_each(|i| { + if let Err(p) = catch_unwind(AssertUnwindSafe(|| for_each(i))) { + if panic.is_none() { + panic = Some(p); + } + } + }); + if let Some(panic) = panic { + resume_unwind(panic); + } } pub type MetadataRef = OwningRef, [u8]>;