@@ -16,7 +16,7 @@ use rustc_errors::emitter::Emitter;
1616use rustc_errors:: translation:: Translator ;
1717use rustc_errors:: {
1818 Diag , DiagArgMap , DiagCtxt , DiagCtxtHandle , DiagMessage , ErrCode , FatalError , FatalErrorMarker ,
19- Level , MultiSpan , Style , Suggestions ,
19+ Level , MultiSpan , Style , Suggestions , catch_fatal_errors ,
2020} ;
2121use rustc_fs_util:: link_or_copy;
2222use rustc_incremental:: {
@@ -403,6 +403,29 @@ struct CompiledModules {
403403 allocator_module : Option < CompiledModule > ,
404404}
405405
406+ enum MaybeLtoModules < B : WriteBackendMethods > {
407+ NoLto {
408+ modules : Vec < CompiledModule > ,
409+ allocator_module : Option < CompiledModule > ,
410+ } ,
411+ FatLto {
412+ cgcx : CodegenContext < B > ,
413+ exported_symbols_for_lto : Arc < Vec < String > > ,
414+ each_linked_rlib_file_for_lto : Vec < PathBuf > ,
415+ needs_fat_lto : Vec < FatLtoInput < B > > ,
416+ lto_import_only_modules :
417+ Vec < ( SerializedModule < <B as WriteBackendMethods >:: ModuleBuffer > , WorkProduct ) > ,
418+ } ,
419+ ThinLto {
420+ cgcx : CodegenContext < B > ,
421+ exported_symbols_for_lto : Arc < Vec < String > > ,
422+ each_linked_rlib_file_for_lto : Vec < PathBuf > ,
423+ needs_thin_lto : Vec < ( String , <B as WriteBackendMethods >:: ThinBuffer ) > ,
424+ lto_import_only_modules :
425+ Vec < ( SerializedModule < <B as WriteBackendMethods >:: ModuleBuffer > , WorkProduct ) > ,
426+ } ,
427+ }
428+
406429fn need_bitcode_in_object ( tcx : TyCtxt < ' _ > ) -> bool {
407430 let sess = tcx. sess ;
408431 sess. opts . cg . embed_bitcode
@@ -1239,7 +1262,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
12391262 allocator_config : Arc < ModuleConfig > ,
12401263 mut allocator_module : Option < ModuleCodegen < B :: Module > > ,
12411264 coordinator_send : Sender < Message < B > > ,
1242- ) -> thread:: JoinHandle < Result < CompiledModules , ( ) > > {
1265+ ) -> thread:: JoinHandle < Result < MaybeLtoModules < B > , ( ) > > {
12431266 let sess = tcx. sess ;
12441267
12451268 let mut each_linked_rlib_for_lto = Vec :: new ( ) ;
@@ -1740,43 +1763,43 @@ fn start_executing_work<B: ExtraBackendMethods>(
17401763 needs_fat_lto. push ( FatLtoInput :: InMemory ( allocator_module) ) ;
17411764 }
17421765
1743- // This uses the implicit token
1744- let module = do_fat_lto (
1745- & cgcx,
1746- shared_emitter. clone ( ) ,
1747- & exported_symbols_for_lto,
1748- & each_linked_rlib_file_for_lto,
1766+ return Ok ( MaybeLtoModules :: FatLto {
1767+ cgcx,
1768+ exported_symbols_for_lto,
1769+ each_linked_rlib_file_for_lto,
17491770 needs_fat_lto,
17501771 lto_import_only_modules,
1751- ) ;
1752- compiled_modules. push ( module) ;
1772+ } ) ;
17531773 } else if !needs_thin_lto. is_empty ( ) || !lto_import_only_modules. is_empty ( ) {
17541774 assert ! ( compiled_modules. is_empty( ) ) ;
17551775 assert ! ( needs_fat_lto. is_empty( ) ) ;
17561776
1757- if cgcx. lto != Lto :: ThinLocal {
1777+ if cgcx. lto == Lto :: ThinLocal {
1778+ compiled_modules. extend ( do_thin_lto (
1779+ & cgcx,
1780+ shared_emitter. clone ( ) ,
1781+ exported_symbols_for_lto,
1782+ each_linked_rlib_file_for_lto,
1783+ needs_thin_lto,
1784+ lto_import_only_modules,
1785+ ) ) ;
1786+ } else {
17581787 if let Some ( allocator_module) = allocator_module. take ( ) {
17591788 let ( name, thin_buffer) = B :: prepare_thin ( allocator_module) ;
17601789 needs_thin_lto. push ( ( name, thin_buffer) ) ;
17611790 }
1762- }
17631791
1764- compiled_modules . extend ( do_thin_lto (
1765- & cgcx,
1766- shared_emitter . clone ( ) ,
1767- exported_symbols_for_lto ,
1768- each_linked_rlib_file_for_lto ,
1769- needs_thin_lto ,
1770- lto_import_only_modules ,
1771- ) ) ;
1792+ return Ok ( MaybeLtoModules :: ThinLto {
1793+ cgcx,
1794+ exported_symbols_for_lto ,
1795+ each_linked_rlib_file_for_lto ,
1796+ needs_thin_lto ,
1797+ lto_import_only_modules ,
1798+ } ) ;
1799+ }
17721800 }
17731801
1774- // Regardless of what order these modules completed in, report them to
1775- // the backend in the same order every time to ensure that we're handing
1776- // out deterministic results.
1777- compiled_modules. sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
1778-
1779- Ok ( CompiledModules {
1802+ Ok ( MaybeLtoModules :: NoLto {
17801803 modules : compiled_modules,
17811804 allocator_module : allocator_module. map ( |allocator_module| {
17821805 B :: codegen ( & cgcx, & shared_emitter, allocator_module, & allocator_config)
@@ -2074,13 +2097,13 @@ impl SharedEmitterMain {
20742097
20752098pub struct Coordinator < B : ExtraBackendMethods > {
20762099 sender : Sender < Message < B > > ,
2077- future : Option < thread:: JoinHandle < Result < CompiledModules , ( ) > > > ,
2100+ future : Option < thread:: JoinHandle < Result < MaybeLtoModules < B > , ( ) > > > ,
20782101 // Only used for the Message type.
20792102 phantom : PhantomData < B > ,
20802103}
20812104
20822105impl < B : ExtraBackendMethods > Coordinator < B > {
2083- fn join ( mut self ) -> std:: thread:: Result < Result < CompiledModules , ( ) > > {
2106+ fn join ( mut self ) -> std:: thread:: Result < Result < MaybeLtoModules < B > , ( ) > > {
20842107 self . future . take ( ) . unwrap ( ) . join ( )
20852108 }
20862109}
@@ -2111,8 +2134,9 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
21112134impl < B : ExtraBackendMethods > OngoingCodegen < B > {
21122135 pub fn join ( self , sess : & Session ) -> ( CodegenResults , FxIndexMap < WorkProductId , WorkProduct > ) {
21132136 self . shared_emitter_main . check ( sess, true ) ;
2114- let compiled_modules = sess. time ( "join_worker_thread" , || match self . coordinator . join ( ) {
2115- Ok ( Ok ( compiled_modules) ) => compiled_modules,
2137+
2138+ let maybe_lto_modules = sess. time ( "join_worker_thread" , || match self . coordinator . join ( ) {
2139+ Ok ( Ok ( maybe_lto_modules) ) => maybe_lto_modules,
21162140 Ok ( Err ( ( ) ) ) => {
21172141 sess. dcx ( ) . abort_if_errors ( ) ;
21182142 panic ! ( "expected abort due to worker thread errors" )
@@ -2124,6 +2148,62 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
21242148
21252149 sess. dcx ( ) . abort_if_errors ( ) ;
21262150
2151+ let ( shared_emitter, shared_emitter_main) = SharedEmitter :: new ( ) ;
2152+
2153+ // Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics
2154+ let compiled_modules = catch_fatal_errors ( || match maybe_lto_modules {
2155+ MaybeLtoModules :: NoLto { modules, allocator_module } => {
2156+ drop ( shared_emitter) ;
2157+ CompiledModules { modules, allocator_module }
2158+ }
2159+ MaybeLtoModules :: FatLto {
2160+ cgcx,
2161+ exported_symbols_for_lto,
2162+ each_linked_rlib_file_for_lto,
2163+ needs_fat_lto,
2164+ lto_import_only_modules,
2165+ } => CompiledModules {
2166+ modules : vec ! [ do_fat_lto(
2167+ & cgcx,
2168+ shared_emitter,
2169+ & exported_symbols_for_lto,
2170+ & each_linked_rlib_file_for_lto,
2171+ needs_fat_lto,
2172+ lto_import_only_modules,
2173+ ) ] ,
2174+ allocator_module : None ,
2175+ } ,
2176+ MaybeLtoModules :: ThinLto {
2177+ cgcx,
2178+ exported_symbols_for_lto,
2179+ each_linked_rlib_file_for_lto,
2180+ needs_thin_lto,
2181+ lto_import_only_modules,
2182+ } => CompiledModules {
2183+ modules : do_thin_lto (
2184+ & cgcx,
2185+ shared_emitter,
2186+ exported_symbols_for_lto,
2187+ each_linked_rlib_file_for_lto,
2188+ needs_thin_lto,
2189+ lto_import_only_modules,
2190+ ) ,
2191+ allocator_module : None ,
2192+ } ,
2193+ } ) ;
2194+
2195+ shared_emitter_main. check ( sess, true ) ;
2196+
2197+ sess. dcx ( ) . abort_if_errors ( ) ;
2198+
2199+ let mut compiled_modules =
2200+ compiled_modules. expect ( "fatal error emitted but not sent to SharedEmitter" ) ;
2201+
2202+ // Regardless of what order these modules completed in, report them to
2203+ // the backend in the same order every time to ensure that we're handing
2204+ // out deterministic results.
2205+ compiled_modules. modules . sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
2206+
21272207 let work_products =
21282208 copy_all_cgu_workproducts_to_incr_comp_cache_dir ( sess, & compiled_modules) ;
21292209 produce_final_output_artifacts ( sess, & compiled_modules, & self . output_filenames ) ;
0 commit comments