@@ -78,10 +78,9 @@ fn reachable_non_generics_provider<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
78
78
let reachable_non_generics = tcx
79
79
. exported_symbols ( LOCAL_CRATE )
80
80
. iter ( )
81
- . filter_map ( |& ( exported_symbol, _ ) | {
81
+ . filter_map ( |& ( exported_symbol, level ) | {
82
82
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) {
85
84
return Some ( def_id)
86
85
}
87
86
}
@@ -110,6 +109,16 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
110
109
return Arc :: new ( vec ! [ ] )
111
110
}
112
111
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
+
113
122
let mut reachable_non_generics: DefIdSet = tcx. reachable_set ( LOCAL_CRATE ) . 0
114
123
. iter ( )
115
124
. filter_map ( |& node_id| {
@@ -176,7 +185,25 @@ fn exported_symbols_provider_local<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
176
185
let mut symbols: Vec < _ > = reachable_non_generics
177
186
. iter ( )
178
187
. 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
+ } ;
180
207
debug ! ( "EXPORTED SYMBOL (local): {} ({:?})" ,
181
208
tcx. symbol_name( Instance :: mono( tcx, def_id) ) ,
182
209
export_level) ;
@@ -222,70 +249,7 @@ pub fn provide(providers: &mut Providers) {
222
249
providers. symbol_export_level = symbol_export_level_provider;
223
250
}
224
251
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
-
287
252
pub fn provide_extern ( providers : & mut Providers ) {
288
- providers. exported_symbols = exported_symbols_provider_extern;
289
253
providers. is_reachable_non_generic = is_reachable_non_generic_provider;
290
254
providers. symbol_export_level = symbol_export_level_provider;
291
255
}
0 commit comments