@@ -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,17 +845,37 @@ 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- }
848+ }
856849
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) ;
850+ // Handle circular dependencies in the standard library.
851+ // See comment before `add_linked_symbol_object` function for the details.
852+ // With msvc-like linkers it's both unnecessary (they support circular dependencies),
853+ // and causes linking issues (when weak lang item symbols are "privatized" by LTO).
854+ let target = & tcx. sess . target ;
855+ if !target. is_like_msvc {
856+ let missing_weak_lang_items: FxHashSet < & Symbol > = info
857+ . used_crates
858+ . iter ( )
859+ . flat_map ( |cnum| {
860+ tcx. missing_lang_items ( * cnum)
861+ . iter ( )
862+ . filter ( |l| lang_items:: required ( tcx, * * l) )
863+ . filter_map ( |item| WEAK_ITEMS_SYMBOLS . get ( item) )
864+ } )
865+ . collect ( ) ;
866+ let prefix = if target. is_like_windows && target. arch == "x86" { "_" } else { "" } ;
867+ info. linked_symbols
868+ . iter_mut ( )
869+ . filter ( |( crate_type, _) | {
870+ !matches ! ( crate_type, CrateType :: Rlib | CrateType :: Staticlib )
871+ } )
872+ . for_each ( |( _, linked_symbols) | {
873+ linked_symbols. extend (
874+ missing_weak_lang_items
875+ . iter ( )
876+ . map ( |item| ( format ! ( "{prefix}{item}" ) , SymbolExportKind :: Text ) ) ,
877+ )
878+ } ) ;
861879 }
862880
863881 let embed_visualizers = tcx. sess . crate_types ( ) . iter ( ) . any ( |& crate_type| match crate_type {
@@ -878,7 +896,7 @@ impl CrateInfo {
878896 }
879897 } ) ;
880898
881- if tcx . sess . target . is_like_msvc && embed_visualizers {
899+ if target. is_like_msvc && embed_visualizers {
882900 info. natvis_debugger_visualizers =
883901 collect_debugger_visualizers_transitive ( tcx, DebuggerVisualizerType :: Natvis ) ;
884902 }
0 commit comments