@@ -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 ( ) ;
@@ -1732,51 +1755,52 @@ fn start_executing_work<B: ExtraBackendMethods>(
17321755 drop ( helper) ;
17331756 assert ! ( work_items. is_empty( ) ) ;
17341757
1735- if !needs_fat_lto. is_empty ( ) {
1758+ if cgcx. lto == Lto :: ThinLocal {
1759+ assert ! ( compiled_modules. is_empty( ) ) ;
1760+ assert ! ( needs_fat_lto. is_empty( ) ) ;
1761+
1762+ compiled_modules. extend ( do_thin_lto (
1763+ & cgcx,
1764+ shared_emitter. clone ( ) ,
1765+ exported_symbols_for_lto,
1766+ each_linked_rlib_file_for_lto,
1767+ needs_thin_lto,
1768+ lto_import_only_modules,
1769+ ) ) ;
1770+ } else if !needs_fat_lto. is_empty ( ) {
17361771 assert ! ( compiled_modules. is_empty( ) ) ;
17371772 assert ! ( needs_thin_lto. is_empty( ) ) ;
17381773
17391774 if let Some ( allocator_module) = allocator_module. take ( ) {
17401775 needs_fat_lto. push ( FatLtoInput :: InMemory ( allocator_module) ) ;
17411776 }
17421777
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,
1778+ return Ok ( MaybeLtoModules :: FatLto {
1779+ cgcx,
1780+ exported_symbols_for_lto,
1781+ each_linked_rlib_file_for_lto,
17491782 needs_fat_lto,
17501783 lto_import_only_modules,
1751- ) ;
1752- compiled_modules. push ( module) ;
1784+ } ) ;
17531785 } else if !needs_thin_lto. is_empty ( ) || !lto_import_only_modules. is_empty ( ) {
17541786 assert ! ( compiled_modules. is_empty( ) ) ;
17551787 assert ! ( needs_fat_lto. is_empty( ) ) ;
17561788
1757- if cgcx. lto != Lto :: ThinLocal {
1758- if let Some ( allocator_module) = allocator_module. take ( ) {
1759- let ( name, thin_buffer) = B :: prepare_thin ( allocator_module) ;
1760- needs_thin_lto. push ( ( name, thin_buffer) ) ;
1761- }
1789+ if let Some ( allocator_module) = allocator_module. take ( ) {
1790+ let ( name, thin_buffer) = B :: prepare_thin ( allocator_module) ;
1791+ needs_thin_lto. push ( ( name, thin_buffer) ) ;
17621792 }
17631793
1764- compiled_modules. extend ( do_thin_lto (
1765- & cgcx,
1766- shared_emitter. clone ( ) ,
1794+ return Ok ( MaybeLtoModules :: ThinLto {
1795+ cgcx,
17671796 exported_symbols_for_lto,
17681797 each_linked_rlib_file_for_lto,
17691798 needs_thin_lto,
17701799 lto_import_only_modules,
1771- ) ) ;
1800+ } ) ;
17721801 }
17731802
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 {
1803+ Ok ( MaybeLtoModules :: NoLto {
17801804 modules : compiled_modules,
17811805 allocator_module : allocator_module. map ( |allocator_module| {
17821806 B :: codegen ( & cgcx, & shared_emitter, allocator_module, & allocator_config)
@@ -2074,13 +2098,13 @@ impl SharedEmitterMain {
20742098
20752099pub struct Coordinator < B : ExtraBackendMethods > {
20762100 sender : Sender < Message < B > > ,
2077- future : Option < thread:: JoinHandle < Result < CompiledModules , ( ) > > > ,
2101+ future : Option < thread:: JoinHandle < Result < MaybeLtoModules < B > , ( ) > > > ,
20782102 // Only used for the Message type.
20792103 phantom : PhantomData < B > ,
20802104}
20812105
20822106impl < B : ExtraBackendMethods > Coordinator < B > {
2083- fn join ( mut self ) -> std:: thread:: Result < Result < CompiledModules , ( ) > > {
2107+ fn join ( mut self ) -> std:: thread:: Result < Result < MaybeLtoModules < B > , ( ) > > {
20842108 self . future . take ( ) . unwrap ( ) . join ( )
20852109 }
20862110}
@@ -2111,8 +2135,9 @@ pub struct OngoingCodegen<B: ExtraBackendMethods> {
21112135impl < B : ExtraBackendMethods > OngoingCodegen < B > {
21122136 pub fn join ( self , sess : & Session ) -> ( CodegenResults , FxIndexMap < WorkProductId , WorkProduct > ) {
21132137 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,
2138+
2139+ let maybe_lto_modules = sess. time ( "join_worker_thread" , || match self . coordinator . join ( ) {
2140+ Ok ( Ok ( maybe_lto_modules) ) => maybe_lto_modules,
21162141 Ok ( Err ( ( ) ) ) => {
21172142 sess. dcx ( ) . abort_if_errors ( ) ;
21182143 panic ! ( "expected abort due to worker thread errors" )
@@ -2124,6 +2149,62 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
21242149
21252150 sess. dcx ( ) . abort_if_errors ( ) ;
21262151
2152+ let ( shared_emitter, shared_emitter_main) = SharedEmitter :: new ( ) ;
2153+
2154+ // Catch fatal errors to ensure shared_emitter_main.check() can emit the actual diagnostics
2155+ let compiled_modules = catch_fatal_errors ( || match maybe_lto_modules {
2156+ MaybeLtoModules :: NoLto { modules, allocator_module } => {
2157+ drop ( shared_emitter) ;
2158+ CompiledModules { modules, allocator_module }
2159+ }
2160+ MaybeLtoModules :: FatLto {
2161+ cgcx,
2162+ exported_symbols_for_lto,
2163+ each_linked_rlib_file_for_lto,
2164+ needs_fat_lto,
2165+ lto_import_only_modules,
2166+ } => CompiledModules {
2167+ modules : vec ! [ do_fat_lto(
2168+ & cgcx,
2169+ shared_emitter,
2170+ & exported_symbols_for_lto,
2171+ & each_linked_rlib_file_for_lto,
2172+ needs_fat_lto,
2173+ lto_import_only_modules,
2174+ ) ] ,
2175+ allocator_module : None ,
2176+ } ,
2177+ MaybeLtoModules :: ThinLto {
2178+ cgcx,
2179+ exported_symbols_for_lto,
2180+ each_linked_rlib_file_for_lto,
2181+ needs_thin_lto,
2182+ lto_import_only_modules,
2183+ } => CompiledModules {
2184+ modules : do_thin_lto (
2185+ & cgcx,
2186+ shared_emitter,
2187+ exported_symbols_for_lto,
2188+ each_linked_rlib_file_for_lto,
2189+ needs_thin_lto,
2190+ lto_import_only_modules,
2191+ ) ,
2192+ allocator_module : None ,
2193+ } ,
2194+ } ) ;
2195+
2196+ shared_emitter_main. check ( sess, true ) ;
2197+
2198+ sess. dcx ( ) . abort_if_errors ( ) ;
2199+
2200+ let mut compiled_modules =
2201+ compiled_modules. expect ( "fatal error emitted but not sent to SharedEmitter" ) ;
2202+
2203+ // Regardless of what order these modules completed in, report them to
2204+ // the backend in the same order every time to ensure that we're handing
2205+ // out deterministic results.
2206+ compiled_modules. modules . sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
2207+
21272208 let work_products =
21282209 copy_all_cgu_workproducts_to_incr_comp_cache_dir ( sess, & compiled_modules) ;
21292210 produce_final_output_artifacts ( sess, & compiled_modules, & self . output_filenames ) ;
0 commit comments