@@ -217,6 +217,7 @@ use rustc_hir::def::DefKind;
217217use  rustc_hir:: def_id:: { DefId ,  DefIdMap ,  LocalDefId } ; 
218218use  rustc_hir:: lang_items:: LangItem ; 
219219use  rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ; 
220+ use  rustc_middle:: middle:: exported_symbols:: ExportedSymbol ; 
220221use  rustc_middle:: mir:: interpret:: { AllocId ,  ErrorHandled ,  GlobalAlloc ,  Scalar } ; 
221222use  rustc_middle:: mir:: mono:: { InstantiationMode ,  MonoItem } ; 
222223use  rustc_middle:: mir:: visit:: Visitor  as  MirVisitor ; 
@@ -232,7 +233,7 @@ use rustc_middle::ty::{
232233use  rustc_middle:: util:: Providers ; 
233234use  rustc_middle:: { bug,  span_bug} ; 
234235use  rustc_session:: Limit ; 
235- use  rustc_session:: config:: EntryFnType ; 
236+ use  rustc_session:: config:: { CrateType ,   EntryFnType } ; 
236237use  rustc_span:: source_map:: { Spanned ,  dummy_spanned,  respan} ; 
237238use  rustc_span:: symbol:: { Ident ,  sym} ; 
238239use  rustc_span:: { DUMMY_SP ,  Span } ; 
@@ -940,28 +941,45 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxtAt<'tcx>, instance: Instance<'tcx>) -
940941        return  true ; 
941942    } ; 
942943
944+     let  def_is_for_mir_only_rlib = if  def_id. krate  == rustc_hir:: def_id:: LOCAL_CRATE  { 
945+         tcx. building_mir_only_rlib ( ) 
946+     }  else  { 
947+         tcx. mir_only_crates ( ( ) ) . iter ( ) . any ( |c| * c == def_id. krate ) 
948+     } ; 
949+ 
943950    if  tcx. is_foreign_item ( def_id)  { 
944-         // Foreign items are always linked against, there's no way of instantiating them. 
945-         return  false ; 
951+         if  def_is_for_mir_only_rlib { 
952+             return  tcx. is_mir_available ( instance. def_id ( ) ) ; 
953+         }  else  { 
954+             // Foreign items are always linked against, there's no way of instantiating them. 
955+             return  false ; 
956+         } 
957+     } 
958+ 
959+     if  def_is_for_mir_only_rlib { 
960+         let  has_mir = tcx. is_mir_available ( instance. def_id ( ) ) ; 
961+         return  has_mir || matches ! ( tcx. def_kind( instance. def_id( ) ) ,  DefKind :: Static  {  .. } ) ; 
946962    } 
947963
948964    if  def_id. is_local ( )  { 
949965        // Local items cannot be referred to locally without monomorphizing them locally. 
950966        return  true ; 
951967    } 
952968
969+     if  !def_is_for_mir_only_rlib { 
970+         if  let  DefKind :: Static  {  .. }  = tcx. def_kind ( def_id)  { 
971+             // We cannot monomorphize statics from upstream crates. 
972+             return  false ; 
973+         } 
974+     } 
975+ 
953976    if  tcx. is_reachable_non_generic ( def_id) 
954977        || instance. polymorphize ( * tcx) . upstream_monomorphization ( * tcx) . is_some ( ) 
955978    { 
956979        // We can link to the item in question, no instance needed in this crate. 
957980        return  false ; 
958981    } 
959982
960-     if  let  DefKind :: Static  {  .. }  = tcx. def_kind ( def_id)  { 
961-         // We cannot monomorphize statics from upstream crates. 
962-         return  false ; 
963-     } 
964- 
965983    if  !tcx. is_mir_available ( def_id)  { 
966984        tcx. dcx ( ) . emit_fatal ( NoOptimizedMir  { 
967985            span :  tcx. def_span ( def_id) , 
@@ -1351,6 +1369,7 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionStrategy) -> Vec<MonoI
13511369        } 
13521370
13531371        collector. push_extra_entry_roots ( ) ; 
1372+         collector. push_extra_roots_from_mir_only_rlibs ( ) ; 
13541373    } 
13551374
13561375    // We can only codegen items that are instantiable - items all of 
@@ -1495,6 +1514,50 @@ impl<'v> RootCollector<'_, 'v> {
14951514
14961515        self . output . push ( create_fn_mono_item ( self . tcx ,  start_instance,  DUMMY_SP ) ) ; 
14971516    } 
1517+ 
1518+     fn  push_extra_roots_from_mir_only_rlibs ( & mut  self )  { 
1519+         // An upstream extern function may be used anywhere in the dependency tree, so we 
1520+         // cannot do any reachability analysis on them. We blindly monomorphize every 
1521+         // extern function declared anywhere in our dependency tree. We must give them 
1522+         // GloballyShared codegen because we don't know if the only call to an upstream 
1523+         // extern function is also upstream: We don't have reachability information. All we 
1524+         // can do is codegen all extern functions and pray for the linker to delete the 
1525+         // ones that are reachable. 
1526+         if  !self . tcx . crate_types ( ) . iter ( ) . any ( |c| !matches ! ( c,  CrateType :: Rlib ) )  { 
1527+             return ; 
1528+         } 
1529+ 
1530+         for  ( symbol,  _info)  in  self 
1531+             . tcx 
1532+             . mir_only_crates ( ( ) ) 
1533+             . into_iter ( ) 
1534+             . flat_map ( |krate| self . tcx . exported_symbols ( * krate) ) 
1535+         { 
1536+             let  def_id = match  symbol { 
1537+                 ExportedSymbol :: NonGeneric ( def_id)  => def_id, 
1538+                 ExportedSymbol :: ThreadLocalShim ( def_id)  => { 
1539+                     let  item = MonoItem :: Fn ( Instance  { 
1540+                         def :  InstanceKind :: ThreadLocalShim ( * def_id) , 
1541+                         args :  GenericArgs :: empty ( ) , 
1542+                     } ) ; 
1543+                     self . output . push ( dummy_spanned ( item) ) ; 
1544+                     continue ; 
1545+                 } 
1546+                 _ => continue , 
1547+             } ; 
1548+             match  self . tcx . def_kind ( def_id)  { 
1549+                 DefKind :: Fn  | DefKind :: AssocFn  => { 
1550+                     let  instance = Instance :: mono ( self . tcx ,  * def_id) ; 
1551+                     let  item = create_fn_mono_item ( self . tcx ,  instance,  DUMMY_SP ) ; 
1552+                     self . output . push ( item) ; 
1553+                 } 
1554+                 DefKind :: Static  {  .. }  => { 
1555+                     self . output . push ( dummy_spanned ( MonoItem :: Static ( * def_id) ) ) ; 
1556+                 } 
1557+                 _ => { } 
1558+             } 
1559+         } 
1560+     } 
14981561} 
14991562
15001563#[ instrument( level = "debug" ,  skip( tcx,  output) ) ]  
0 commit comments