@@ -12,7 +12,7 @@ use crate::traits::*;
1212use crate :: { CachedModuleCodegen , CompiledModule , CrateInfo , MemFlags , ModuleCodegen , ModuleKind } ;
1313
1414use rustc_attr as attr;
15- use rustc_data_structures:: fx:: FxHashMap ;
15+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
1616use rustc_data_structures:: profiling:: { get_resident_set_size, print_time_passes_entry} ;
1717
1818use rustc_data_structures:: sync:: par_iter;
@@ -21,10 +21,12 @@ use rustc_data_structures::sync::ParallelIterator;
2121use rustc_hir as hir;
2222use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
2323use rustc_hir:: lang_items:: LangItem ;
24+ use rustc_hir:: weak_lang_items:: WEAK_ITEMS_SYMBOLS ;
2425use rustc_index:: vec:: Idx ;
2526use rustc_metadata:: EncodedMetadata ;
2627use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
2728use rustc_middle:: middle:: exported_symbols;
29+ use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
2830use rustc_middle:: middle:: lang_items;
2931use rustc_middle:: mir:: mono:: { CodegenUnit , CodegenUnitNameBuilder , MonoItem } ;
3032use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , TyAndLayout } ;
@@ -34,6 +36,7 @@ use rustc_session::cgu_reuse_tracker::CguReuse;
3436use rustc_session:: config:: { self , CrateType , EntryFnType , OutputType } ;
3537use rustc_session:: Session ;
3638use rustc_span:: symbol:: sym;
39+ use rustc_span:: Symbol ;
3740use rustc_span:: { DebuggerVisualizerFile , DebuggerVisualizerType } ;
3841use rustc_target:: abi:: { Align , VariantIdx } ;
3942
@@ -815,21 +818,16 @@ impl CrateInfo {
815818 crate_name : Default :: default ( ) ,
816819 used_crates,
817820 used_crate_source : Default :: default ( ) ,
818- lang_item_to_crate : Default :: default ( ) ,
819- missing_lang_items : Default :: default ( ) ,
820821 dependency_formats : tcx. dependency_formats ( ( ) ) . clone ( ) ,
821822 windows_subsystem,
822823 natvis_debugger_visualizers : Default :: default ( ) ,
823824 } ;
824- let lang_items = tcx. lang_items ( ) ;
825-
826825 let crates = tcx. crates ( ( ) ) ;
827826
828827 let n_crates = crates. len ( ) ;
829828 info. native_libraries . reserve ( n_crates) ;
830829 info. crate_name . reserve ( n_crates) ;
831830 info. used_crate_source . reserve ( n_crates) ;
832- info. missing_lang_items . reserve ( n_crates) ;
833831
834832 for & cnum in crates. iter ( ) {
835833 info. native_libraries
@@ -847,19 +845,31 @@ impl CrateInfo {
847845 if tcx. is_no_builtins ( cnum) {
848846 info. is_no_builtins . insert ( cnum) ;
849847 }
850- let missing = tcx. missing_lang_items ( cnum) ;
851- for & item in missing. iter ( ) {
852- if let Ok ( id) = lang_items. require ( item) {
853- info. lang_item_to_crate . insert ( item, id. krate ) ;
854- }
855- }
856-
857- // No need to look for lang items that don't actually need to exist.
858- let missing =
859- missing. iter ( ) . cloned ( ) . filter ( |& l| lang_items:: required ( tcx, l) ) . collect ( ) ;
860- info. missing_lang_items . insert ( cnum, missing) ;
861848 }
862849
850+ // Handle circular dependencies in the standard library.
851+ // See comment before `add_linked_symbol_object` function for the details.
852+ let missing_weak_lang_items: FxHashSet < & Symbol > = info
853+ . used_crates
854+ . iter ( )
855+ . flat_map ( |cnum| {
856+ tcx. missing_lang_items ( * cnum)
857+ . iter ( )
858+ . filter ( |l| lang_items:: required ( tcx, * * l) )
859+ . filter_map ( |item| WEAK_ITEMS_SYMBOLS . get ( item) )
860+ } )
861+ . collect ( ) ;
862+ info. linked_symbols
863+ . iter_mut ( )
864+ . filter ( |( crate_type, _) | !matches ! ( crate_type, CrateType :: Rlib | CrateType :: Staticlib ) )
865+ . for_each ( |( _, linked_symbols) | {
866+ linked_symbols. extend (
867+ missing_weak_lang_items
868+ . iter ( )
869+ . map ( |item| ( item. to_string ( ) , SymbolExportKind :: Text ) ) ,
870+ )
871+ } ) ;
872+
863873 let embed_visualizers = tcx. sess . crate_types ( ) . iter ( ) . any ( |& crate_type| match crate_type {
864874 CrateType :: Executable | CrateType :: Dylib | CrateType :: Cdylib => {
865875 // These are crate types for which we invoke the linker and can embed
0 commit comments