@@ -78,10 +78,9 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
7878    let  reachable_non_generics = tcx
7979        . exported_symbols ( LOCAL_CRATE ) 
8080        . iter ( ) 
81-         . filter_map ( |& ( exported_symbol,  _ ) | { 
81+         . filter_map ( |& ( exported_symbol,  level ) | { 
8282            if  let  ExportedSymbol :: NonGeneric ( def_id)  = exported_symbol { 
83-                 if  tcx. symbol_export_level ( def_id) 
84-                       . is_below_threshold ( export_threshold)  { 
83+                 if  level. is_below_threshold ( export_threshold)  { 
8584                    return  Some ( def_id) 
8685                } 
8786            } 
@@ -110,6 +109,16 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
110109        return  Arc :: new ( vec ! [ ] ) 
111110    } 
112111
112+     // Check to see if this crate is a "special runtime crate". These 
113+     // crates, implementation details of the standard library, typically 
114+     // have a bunch of `pub extern` and `#[no_mangle]` functions as the 
115+     // ABI between them. We don't want their symbols to have a `C` 
116+     // export level, however, as they're just implementation details. 
117+     // Down below we'll hardwire all of the symbols to the `Rust` export 
118+     // level instead. 
119+     let  special_runtime_crate = tcx. is_panic_runtime ( LOCAL_CRATE )  ||
120+         tcx. is_compiler_builtins ( LOCAL_CRATE ) ; 
121+ 
113122    let  mut  reachable_non_generics:  DefIdSet  = tcx. reachable_set ( LOCAL_CRATE ) . 0 
114123        . iter ( ) 
115124        . filter_map ( |& node_id| { 
@@ -176,7 +185,25 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
176185    let  mut  symbols:  Vec < _ >  = reachable_non_generics
177186        . iter ( ) 
178187        . map ( |& def_id| { 
179-             let  export_level = tcx. symbol_export_level ( def_id) ; 
188+             let  export_level = if  special_runtime_crate { 
189+                 let  name = tcx. symbol_name ( Instance :: mono ( tcx,  def_id) ) ; 
190+                 // We can probably do better here by just ensuring that 
191+                 // it has hidden visibility rather than public 
192+                 // visibility, as this is primarily here to ensure it's 
193+                 // not stripped during LTO. 
194+                 // 
195+                 // In general though we won't link right if these 
196+                 // symbols are stripped, and LTO currently strips them. 
197+                 if  & * name == "rust_eh_personality"  ||
198+                    & * name == "rust_eh_register_frames"  ||
199+                    & * name == "rust_eh_unregister_frames"  { 
200+                     SymbolExportLevel :: C 
201+                 }  else  { 
202+                     SymbolExportLevel :: Rust 
203+                 } 
204+             }  else  { 
205+                 tcx. symbol_export_level ( def_id) 
206+             } ; 
180207            debug ! ( "EXPORTED SYMBOL (local): {} ({:?})" , 
181208                   tcx. symbol_name( Instance :: mono( tcx,  def_id) ) , 
182209                   export_level) ; 
@@ -222,70 +249,7 @@ pub fn provide(providers: &mut Providers) {
222249    providers. symbol_export_level  = symbol_export_level_provider; 
223250} 
224251
225- fn  exported_symbols_provider_extern < ' a ,  ' tcx > ( tcx :  TyCtxt < ' a ,  ' tcx ,  ' tcx > , 
226-                                               cnum :  CrateNum ) 
227-                                               -> Arc < Vec < ( ExportedSymbol , 
228-                                                           SymbolExportLevel ) > > 
229- { 
230-     // If this crate is a plugin and/or a custom derive crate, then 
231-     // we're not even going to link those in so we skip those crates. 
232-     if  tcx. plugin_registrar_fn ( cnum) . is_some ( )  ||
233-        tcx. derive_registrar_fn ( cnum) . is_some ( )  { 
234-         return  Arc :: new ( Vec :: new ( ) ) 
235-     } 
236- 
237-     // Check to see if this crate is a "special runtime crate". These 
238-     // crates, implementation details of the standard library, typically 
239-     // have a bunch of `pub extern` and `#[no_mangle]` functions as the 
240-     // ABI between them. We don't want their symbols to have a `C` 
241-     // export level, however, as they're just implementation details. 
242-     // Down below we'll hardwire all of the symbols to the `Rust` export 
243-     // level instead. 
244-     let  special_runtime_crate =
245-         tcx. is_panic_runtime ( cnum)  || tcx. is_compiler_builtins ( cnum) ; 
246- 
247-     let  mut  crate_exports:  Vec < _ >  = tcx
248-         . reachable_non_generics ( cnum) 
249-         . iter ( ) 
250-         . map ( |& def_id| { 
251-             let  export_level = if  special_runtime_crate { 
252-                 let  name = tcx. symbol_name ( Instance :: mono ( tcx,  def_id) ) ; 
253-                 // We can probably do better here by just ensuring that 
254-                 // it has hidden visibility rather than public 
255-                 // visibility, as this is primarily here to ensure it's 
256-                 // not stripped during LTO. 
257-                 // 
258-                 // In general though we won't link right if these 
259-                 // symbols are stripped, and LTO currently strips them. 
260-                 if  & * name == "rust_eh_personality"  ||
261-                    & * name == "rust_eh_register_frames"  ||
262-                    & * name == "rust_eh_unregister_frames"  { 
263-                     SymbolExportLevel :: C 
264-                 }  else  { 
265-                     SymbolExportLevel :: Rust 
266-                 } 
267-             }  else  { 
268-                 tcx. symbol_export_level ( def_id) 
269-             } ; 
270- 
271-             debug ! ( "EXPORTED SYMBOL (re-export): {} ({:?})" , 
272-                    tcx. symbol_name( Instance :: mono( tcx,  def_id) ) , 
273-                    export_level) ; 
274- 
275-             ( ExportedSymbol :: NonGeneric ( def_id) ,  export_level) 
276-         } ) 
277-         . collect ( ) ; 
278- 
279-     // Sort so we get a stable incr. comp. hash. 
280-     crate_exports. sort_unstable_by ( |& ( ref  symbol1,  ..) ,  & ( ref  symbol2,  ..) | { 
281-         symbol1. compare_stable ( tcx,  symbol2) 
282-     } ) ; 
283- 
284-     Arc :: new ( crate_exports) 
285- } 
286- 
287252pub  fn  provide_extern ( providers :  & mut  Providers )  { 
288-     providers. exported_symbols  = exported_symbols_provider_extern; 
289253    providers. is_reachable_non_generic  = is_reachable_non_generic_provider; 
290254    providers. symbol_export_level  = symbol_export_level_provider; 
291255} 
0 commit comments