1
1
use std:: assert_matches:: assert_matches;
2
2
use std:: marker:: PhantomData ;
3
+ use std:: panic:: AssertUnwindSafe ;
3
4
use std:: path:: { Path , PathBuf } ;
4
5
use std:: sync:: Arc ;
5
6
use std:: sync:: mpsc:: { Receiver , Sender , channel} ;
@@ -14,8 +15,8 @@ use rustc_data_structures::profiling::{SelfProfilerRef, VerboseTimingGuard};
14
15
use rustc_errors:: emitter:: Emitter ;
15
16
use rustc_errors:: translation:: Translator ;
16
17
use 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 ,
19
20
} ;
20
21
use rustc_fs_util:: link_or_copy;
21
22
use rustc_incremental:: {
@@ -1722,37 +1723,10 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
1722
1723
let cgcx = cgcx. clone ( ) ;
1723
1724
1724
1725
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 ( || {
1753
1727
let module_config = cgcx. config ( work. module_kind ( ) ) ;
1754
1728
1755
- Some ( match work {
1729
+ match work {
1756
1730
WorkItem :: Optimize ( m) => {
1757
1731
let _timer =
1758
1732
cgcx. prof . generic_activity_with_arg ( "codegen_module_optimize" , & * m. name ) ;
@@ -1788,8 +1762,23 @@ fn spawn_work<'a, B: ExtraBackendMethods>(
1788
1762
cgcx. prof . generic_activity_with_arg ( "codegen_module_perform_lto" , m. name ( ) ) ;
1789
1763
execute_thin_lto_work_item ( & cgcx, m, module_config)
1790
1764
}
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 ) } ,
1792
1780
} ;
1781
+ drop ( coordinator_send. send ( msg) ) ;
1793
1782
} )
1794
1783
. expect ( "failed to spawn work thread" ) ;
1795
1784
}
0 commit comments