11use std:: assert_matches:: assert_matches;
22use std:: marker:: PhantomData ;
3+ use std:: panic:: AssertUnwindSafe ;
34use std:: path:: { Path , PathBuf } ;
45use std:: sync:: Arc ;
56use std:: sync:: mpsc:: { Receiver , Sender , channel} ;
@@ -14,8 +15,8 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
1415use rustc_errors:: emitter:: Emitter ;
1516use rustc_errors:: translation:: Translator ;
1617use rustc_errors:: {
17- Diag , DiagArgMap , DiagCtxt , DiagMessage , ErrCode , FatalError , Level , MultiSpan , Style ,
18- Suggestions ,
18+ Diag , DiagArgMap , DiagCtxt , DiagMessage , ErrCode , FatalError , FatalErrorMarker , Level ,
19+ MultiSpan , Style , Suggestions ,
1920} ;
2021use rustc_fs_util:: link_or_copy;
2122use rustc_incremental:: {
@@ -1722,37 +1723,10 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
17221723 let cgcx = cgcx. clone ( ) ;
17231724
17241725 B :: spawn_named_thread ( cgcx. time_trace , work. short_description ( ) , move || {
1725- // Set up a destructor which will fire off a message that we're done as
1726- // we exit.
1727- struct Bomb < B : ExtraBackendMethods > {
1728- coordinator_send : Sender < Message < B > > ,
1729- result : Option < Result < WorkItemResult < B > , FatalError > > ,
1730- }
1731- impl < B : ExtraBackendMethods > Drop for Bomb < B > {
1732- fn drop ( & mut self ) {
1733- let msg = match self . result . take ( ) {
1734- Some ( Ok ( result) ) => Message :: WorkItem :: < B > { result : Ok ( result) } ,
1735- Some ( Err ( FatalError ) ) => {
1736- Message :: WorkItem :: < B > { result : Err ( Some ( WorkerFatalError ) ) }
1737- }
1738- None => Message :: WorkItem :: < B > { result : Err ( None ) } ,
1739- } ;
1740- drop ( self . coordinator_send . send ( msg) ) ;
1741- }
1742- }
1743-
1744- let mut bomb = Bomb :: < B > { coordinator_send, result : None } ;
1745-
1746- // Execute the work itself, and if it finishes successfully then flag
1747- // ourselves as a success as well.
1748- //
1749- // Note that we ignore any `FatalError` coming out of `execute_work_item`,
1750- // as a diagnostic was already sent off to the main thread - just
1751- // surface that there was an error in this worker.
1752- bomb. result = {
1726+ let result = std:: panic:: catch_unwind ( AssertUnwindSafe ( || {
17531727 let module_config = cgcx. config ( work. module_kind ( ) ) ;
17541728
1755- Some ( match work {
1729+ match work {
17561730 WorkItem :: Optimize ( m) => {
17571731 let _timer =
17581732 cgcx. prof . generic_activity_with_arg ( "codegen_module_optimize" , & * m. name ) ;
@@ -1788,8 +1762,23 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
17881762 cgcx. prof . generic_activity_with_arg ( "codegen_module_perform_lto" , m. name ( ) ) ;
17891763 execute_thin_lto_work_item ( & cgcx, m, module_config)
17901764 }
1791- } )
1765+ }
1766+ } ) ) ;
1767+
1768+ let msg = match result {
1769+ Ok ( Ok ( result) ) => Message :: WorkItem :: < B > { result : Ok ( result) } ,
1770+
1771+ // We ignore any `FatalError` coming out of `execute_work_item`, as a
1772+ // diagnostic was already sent off to the main thread - just surface
1773+ // that there was an error in this worker.
1774+ Ok ( Err ( FatalError ) ) => Message :: WorkItem :: < B > { result : Err ( Some ( WorkerFatalError ) ) } ,
1775+ Err ( err) if err. is :: < FatalErrorMarker > ( ) => {
1776+ Message :: WorkItem :: < B > { result : Err ( Some ( WorkerFatalError ) ) }
1777+ }
1778+
1779+ Err ( _) => Message :: WorkItem :: < B > { result : Err ( None ) } ,
17921780 } ;
1781+ drop ( coordinator_send. send ( msg) ) ;
17931782 } )
17941783 . expect ( "failed to spawn work thread" ) ;
17951784}
0 commit comments