@@ -12,7 +12,7 @@ use crate::traits::*;
12
12
use crate :: { CachedModuleCodegen , CompiledModule , CrateInfo , MemFlags , ModuleCodegen , ModuleKind } ;
13
13
14
14
use rustc_attr as attr;
15
- use rustc_data_structures:: fx:: FxHashMap ;
15
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
16
16
use rustc_data_structures:: profiling:: { get_resident_set_size, print_time_passes_entry} ;
17
17
18
18
use rustc_data_structures:: sync:: par_iter;
@@ -21,10 +21,12 @@ use rustc_data_structures::sync::ParallelIterator;
21
21
use rustc_hir as hir;
22
22
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
23
23
use rustc_hir:: lang_items:: LangItem ;
24
+ use rustc_hir:: weak_lang_items:: WEAK_ITEMS_SYMBOLS ;
24
25
use rustc_index:: vec:: Idx ;
25
26
use rustc_metadata:: EncodedMetadata ;
26
27
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
27
28
use rustc_middle:: middle:: exported_symbols;
29
+ use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
28
30
use rustc_middle:: middle:: lang_items;
29
31
use rustc_middle:: mir:: mono:: { CodegenUnit , CodegenUnitNameBuilder , MonoItem } ;
30
32
use rustc_middle:: ty:: layout:: { HasTyCtxt , LayoutOf , TyAndLayout } ;
@@ -34,6 +36,7 @@ use rustc_session::cgu_reuse_tracker::CguReuse;
34
36
use rustc_session:: config:: { self , CrateType , EntryFnType , OutputType } ;
35
37
use rustc_session:: Session ;
36
38
use rustc_span:: symbol:: sym;
39
+ use rustc_span:: Symbol ;
37
40
use rustc_span:: { DebuggerVisualizerFile , DebuggerVisualizerType } ;
38
41
use rustc_target:: abi:: { Align , VariantIdx } ;
39
42
@@ -815,21 +818,16 @@ impl CrateInfo {
815
818
crate_name : Default :: default ( ) ,
816
819
used_crates,
817
820
used_crate_source : Default :: default ( ) ,
818
- lang_item_to_crate : Default :: default ( ) ,
819
- missing_lang_items : Default :: default ( ) ,
820
821
dependency_formats : tcx. dependency_formats ( ( ) ) . clone ( ) ,
821
822
windows_subsystem,
822
823
natvis_debugger_visualizers : Default :: default ( ) ,
823
824
} ;
824
- let lang_items = tcx. lang_items ( ) ;
825
-
826
825
let crates = tcx. crates ( ( ) ) ;
827
826
828
827
let n_crates = crates. len ( ) ;
829
828
info. native_libraries . reserve ( n_crates) ;
830
829
info. crate_name . reserve ( n_crates) ;
831
830
info. used_crate_source . reserve ( n_crates) ;
832
- info. missing_lang_items . reserve ( n_crates) ;
833
831
834
832
for & cnum in crates. iter ( ) {
835
833
info. native_libraries
@@ -847,17 +845,37 @@ impl CrateInfo {
847
845
if tcx. is_no_builtins ( cnum) {
848
846
info. is_no_builtins . insert ( cnum) ;
849
847
}
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
+ }
856
849
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
+ } ) ;
861
879
}
862
880
863
881
let embed_visualizers = tcx. sess . crate_types ( ) . iter ( ) . any ( |& crate_type| match crate_type {
@@ -878,7 +896,7 @@ impl CrateInfo {
878
896
}
879
897
} ) ;
880
898
881
- if tcx . sess . target . is_like_msvc && embed_visualizers {
899
+ if target. is_like_msvc && embed_visualizers {
882
900
info. natvis_debugger_visualizers =
883
901
collect_debugger_visualizers_transitive ( tcx, DebuggerVisualizerType :: Natvis ) ;
884
902
}
0 commit comments