@@ -185,6 +185,7 @@ use rustc_middle::ty::{
185
185
} ;
186
186
use rustc_middle:: ty:: { GenericArgKind , GenericArgs } ;
187
187
use rustc_middle:: { middle:: codegen_fn_attrs:: CodegenFnAttrFlags , mir:: visit:: TyContext } ;
188
+ use rustc_session:: config:: CrateType ;
188
189
use rustc_session:: config:: EntryFnType ;
189
190
use rustc_session:: lint:: builtin:: LARGE_ASSIGNMENTS ;
190
191
use rustc_session:: Limit ;
@@ -317,6 +318,7 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<
317
318
}
318
319
319
320
collector. push_extra_entry_roots ( ) ;
321
+ collector. push_extra_roots_from_mir_only_rlibs ( ) ;
320
322
}
321
323
322
324
// We can only codegen items that are instantiable - items all of
@@ -976,15 +978,15 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: &Instance<'tcx>) ->
976
978
} ;
977
979
978
980
if tcx. is_foreign_item ( def_id) {
979
- if tcx. sess . opts . unstable_opts . mir_only_libs {
981
+ if tcx. building_mir_only_rlib ( ) {
980
982
return tcx. is_mir_available ( instance. def_id ( ) ) ;
981
983
} else {
982
984
// Foreign items are always linked against, there's no way of instantiating them.
983
985
return false ;
984
986
}
985
987
}
986
988
987
- if tcx. sess . opts . unstable_opts . mir_only_libs {
989
+ if tcx. building_mir_only_rlib ( ) {
988
990
let has_mir = tcx. is_mir_available ( instance. def_id ( ) ) ;
989
991
return has_mir || matches ! ( tcx. def_kind( instance. def_id( ) ) , DefKind :: Static ( _) ) ;
990
992
}
@@ -1281,7 +1283,6 @@ impl<'v> RootCollector<'_, 'v> {
1281
1283
let Some ( ( main_def_id, EntryFnType :: Main { .. } ) ) = self . entry_fn else {
1282
1284
return ;
1283
1285
} ;
1284
-
1285
1286
let start_def_id = self . tcx . require_lang_item ( LangItem :: Start , None ) ;
1286
1287
let main_ret_ty = self . tcx . fn_sig ( main_def_id) . no_bound_vars ( ) . unwrap ( ) . output ( ) ;
1287
1288
@@ -1305,34 +1306,50 @@ impl<'v> RootCollector<'_, 'v> {
1305
1306
. unwrap ( ) ;
1306
1307
1307
1308
self . output . push ( create_fn_mono_item ( self . tcx , start_instance, DUMMY_SP ) ) ;
1309
+ }
1308
1310
1311
+ fn push_extra_roots_from_mir_only_rlibs ( & mut self ) {
1309
1312
// An upstream extern function may be used anywhere in the dependency tree, so we
1310
1313
// cannot do any reachability analysis on them. We blindly monomorphize every
1311
1314
// extern function declared anywhere in our dependency tree. We must give them
1312
1315
// GloballyShared codegen because we don't know if the only call to an upstream
1313
1316
// extern function is also upstream: We don't have reachability information. All we
1314
1317
// can do is codegen all extern functions and pray for the linker to delete the
1315
1318
// ones that are reachable.
1316
- if self . tcx . building_mir_only_bin ( ) {
1317
- for ( symbol, _info) in
1318
- self . tcx . crates ( ( ) ) . into_iter ( ) . flat_map ( |krate| self . tcx . exported_symbols ( * krate) )
1319
- {
1320
- let def_id = match symbol {
1321
- ExportedSymbol :: NonGeneric ( def_id) => def_id,
1322
- _ => {
1323
- continue ;
1324
- }
1325
- } ;
1326
- if self . tcx . def_kind ( def_id) != DefKind :: Fn {
1319
+ if !self . tcx . crate_types ( ) . iter ( ) . any ( |c| !matches ! ( c, CrateType :: Rlib ) ) {
1320
+ return ;
1321
+ }
1322
+
1323
+ for ( symbol, _info) in self
1324
+ . tcx
1325
+ . mir_only_crates ( ( ) )
1326
+ . into_iter ( )
1327
+ . flat_map ( |krate| self . tcx . exported_symbols ( * krate) )
1328
+ {
1329
+ let def_id = match symbol {
1330
+ ExportedSymbol :: NonGeneric ( def_id) => def_id,
1331
+ ExportedSymbol :: ThreadLocalShim ( def_id) => {
1332
+ let item = MonoItem :: Fn ( Instance {
1333
+ def : InstanceDef :: ThreadLocalShim ( * def_id) ,
1334
+ args : GenericArgs :: empty ( ) ,
1335
+ } ) ;
1336
+ self . output . push ( respan ( DUMMY_SP , item) ) ;
1327
1337
continue ;
1328
1338
}
1329
- let instance = Instance :: mono ( self . tcx , * def_id) ;
1330
- // FIXME: This is probably not the right span. What is?
1331
- let item = create_fn_mono_item ( self . tcx , instance, DUMMY_SP ) ;
1332
- // FIXME: Do we need this check?
1333
- if !self . output . iter ( ) . any ( |out| out. node . def_id ( ) == * def_id) {
1334
- self . output . push ( item) ;
1339
+ _ => continue ,
1340
+ } ;
1341
+ match self . tcx . def_kind ( def_id) {
1342
+ DefKind :: Fn | DefKind :: AssocFn => {
1343
+ let instance = Instance :: mono ( self . tcx , * def_id) ;
1344
+ let item = create_fn_mono_item ( self . tcx , instance, DUMMY_SP ) ;
1345
+ if !self . output . iter ( ) . any ( |out| out. node . def_id ( ) == * def_id) {
1346
+ self . output . push ( item) ;
1347
+ }
1348
+ }
1349
+ DefKind :: Static ( _) => {
1350
+ self . output . push ( dummy_spanned ( MonoItem :: Static ( * def_id) ) ) ;
1335
1351
}
1352
+ _ => { }
1336
1353
}
1337
1354
}
1338
1355
}
0 commit comments