Change:
found while checking with When you run the snipped above with , rustc panics, but the exit status is as if there was just a normal compiler error, instead of a . This tripped up automatic ice-reduction that relies on a somewhat familiar exit code when the program crashes :sweat_smile:
is the problematic line here that turns ICEs into "normal" fatal errors that call exit(1) though actually at least with the non parallel compiler i'm very surprised that we're ending up in a query in the first place after panicking.
It seems that current stable does correctly exit with here... I bisected the exit code 101 -exit code 1 change with a crashing file ( ) and got to Regression in nightly-2023-08-31 Regression in cc /
WG-prioritization assigning priority (). label -I-prioritize +P-medium

Discussion:
} } <ins> /// This is a marker for a fatal compiler error used with `resume_unwind`. pub struct FatalErrorMarker; </ins> /// Turns a closure that takes an `&mut Formatter` into something that can be display-formatted. pub fn make_display(f: impl Fn(&mut fmt::Formatter<'_>) -> fmt::Result) -> impl fmt::Display { struct Printer<F> {

#![allow(dead_code)] <ins> use crate::sync::IntoDynSyncSend; use crate::FatalErrorMarker; </ins> use parking_lot::Mutex; use std::any::Any; use std::panic::{catch_unwind, resume_unwind, AssertUnwindSafe};

/// continuing with unwinding. It's also used for the non-parallel code to ensure error message /// output match the parallel compiler for testing purposes. pub struct ParallelGuard { <del> panic: Mutex<Option<Box<dyn Any + Send + 'static>>>, </del> <ins> panic: Mutex<Option<IntoDynSyncSend<Box<dyn Any + Send + 'static>>>>, </ins> } impl ParallelGuard { pub fn run<R>(&self, f: impl FnOnce() -> R) -> Option<R> { catch_unwind(AssertUnwindSafe(f)) .map_err(|err| { <del> *self.panic.lock() = Some(err); </del> <ins> let mut panic = self.panic.lock(); if panic.is_none() || !(*err).is::<FatalErrorMarker>() { *panic = Some(IntoDynSyncSend(err)); } </ins> }) .ok() }

pub fn parallel_guard<R>(f: impl FnOnce(&ParallelGuard) -> R) -> R { let guard = ParallelGuard { panic: Mutex::new(None) }; let ret = f(&guard); <del> if let Some(panic) = guard.panic.into_inner() { </del> <ins> if let Some(IntoDynSyncSend(panic)) = guard.panic.into_inner() { </ins> resume_unwind(panic); } ret

parallel!(impl $fblock [$block, $($c,)*] [$($rest),*]) }; (impl $fblock:block [$($blocks:expr,)*] []) => { <del> ::rustc_data_structures::sync::scope(|s| { $(let block = rustc_data_structures::sync::FromDyn::from(|| $blocks); s.spawn(move |_| block.into_inner()());)* (|| $fblock)(); </del> <ins> $crate::sync::parallel_guard(|guard| { $crate::sync::scope(|s| { $( let block = $crate::sync::FromDyn::from(|| $blocks); s.spawn(move |_| { guard.run(move || block.into_inner()()); }); )* guard.run(|| $fblock); }); </ins> }); }; ($fblock:block, $($blocks:block),*) => { <del> if rustc_data_structures::sync::is_dyn_thread_safe() { </del> <ins> if $crate::sync::is_dyn_thread_safe() { </ins> // 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.

if mode::is_dyn_thread_safe() { let oper_a = FromDyn::from(oper_a); let oper_b = FromDyn::from(oper_b); <del> let (a, b) = rayon::join( move || FromDyn::from(oper_a.into_inner()()), move || FromDyn::from(oper_b.into_inner()()), ); (a.into_inner(), b.into_inner()) </del> <ins> let (a, b) = parallel_guard(|guard| { rayon::join( move || guard.run(move || FromDyn::from(oper_a.into_inner()())), move || guard.run(move || FromDyn::from(oper_b.into_inner()())), ) }); (a.unwrap().into_inner(), b.unwrap().into_inner()) </ins> } else { super::disabled::join(oper_a, oper_b) }

#[must_use] pub struct FatalError; <del> pub struct FatalErrorMarker; </del> <ins> pub use rustc_data_structures::FatalErrorMarker; </ins> // Don't implement Send on FatalError. This makes it impossible to panic!(FatalError). // We don't want to invoke the panic handler and print a backtrace for fatal errors.