2424use std:: cell:: Ref ;
2525use std:: collections:: BTreeSet ;
2626use std:: ops:: ControlFlow ;
27- use std:: sync:: { Arc , Once } ;
27+ use std:: sync:: { Arc , OnceLock } ;
2828use std:: { fmt, mem} ;
2929
3030use diagnostics:: { ParamKindInEnumDiscriminant , ParamKindInNonTrivialAnonConst } ;
@@ -633,7 +633,22 @@ impl BindingKey {
633633 }
634634}
635635
636- type Resolutions < ' ra > = CmRefCell < FxIndexMap < BindingKey , NameResolutionRef < ' ra > > > ;
636+ type ResolutionTable < ' ra > = FxIndexMap < BindingKey , NameResolutionRef < ' ra > > ;
637+
638+ enum Resolutions < ' ra > {
639+ Local ( CmRefCell < ResolutionTable < ' ra > > ) ,
640+ Extern ( OnceLock < CmRefCell < ResolutionTable < ' ra > > > ) ,
641+ }
642+
643+ impl < ' ra > Resolutions < ' ra > {
644+ fn new ( local : bool ) -> Self {
645+ if local {
646+ Resolutions :: Local ( Default :: default ( ) )
647+ } else {
648+ Resolutions :: Extern ( Default :: default ( ) )
649+ }
650+ }
651+ }
637652
638653/// One node in the tree of modules.
639654///
@@ -655,8 +670,6 @@ struct ModuleData<'ra> {
655670 /// Mapping between names and their (possibly in-progress) resolutions in this module.
656671 /// Resolutions in modules from other crates are not populated until accessed.
657672 lazy_resolutions : Resolutions < ' ra > ,
658- /// True if this is a module from other crate that needs to be populated on access.
659- populate_on_access : Once ,
660673 /// Used to disambiguate underscore items (`const _: T = ...`) in the module.
661674 underscore_disambiguator : CmCell < u32 > ,
662675
@@ -710,6 +723,7 @@ impl<'ra> ModuleData<'ra> {
710723 vis : Visibility < ModId > ,
711724 arenas : & ' ra ResolverArenas < ' ra > ,
712725 ) -> Self {
726+ let lazy_resolutions = Resolutions :: new ( kind. is_local ( ) ) ;
713727 let self_decl = match kind {
714728 ModuleKind :: Def ( def_kind, def_id, ..) => {
715729 let expn_id = expansion. as_local ( ) . unwrap_or ( LocalExpnId :: ROOT ) ;
@@ -720,8 +734,7 @@ impl<'ra> ModuleData<'ra> {
720734 ModuleData {
721735 parent,
722736 kind,
723- lazy_resolutions : Default :: default ( ) ,
724- populate_on_access : Once :: new ( ) ,
737+ lazy_resolutions,
725738 underscore_disambiguator : CmCell :: new ( 0 ) ,
726739 unexpanded_invocations : Default :: default ( ) ,
727740 no_implicit_prelude,
@@ -2162,15 +2175,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
21622175 self . tcx . hir_arena . alloc_slice ( & import_ids)
21632176 }
21642177
2165- fn resolutions ( & self , module : Module < ' ra > ) -> & ' ra Resolutions < ' ra > {
2166- if !module. is_local ( ) {
2167- // as long as 1 thread is building this external table, all other threads will wait
2168- module. populate_on_access . call_once ( || {
2169- * module. lazy_resolutions . borrow_mut_unchecked ( ) =
2170- self . build_reduced_graph_external ( module. expect_extern ( ) ) ;
2171- } ) ;
2178+ fn resolutions ( & self , module : Module < ' ra > ) -> & ' ra CmRefCell < ResolutionTable < ' ra > > {
2179+ match & module. 0 . 0 . lazy_resolutions {
2180+ Resolutions :: Local ( local_res) => local_res,
2181+ Resolutions :: Extern ( extern_res) => {
2182+ // as long as 1 thread is building this external table, all other threads will wait
2183+ extern_res. get_or_init ( || {
2184+ CmRefCell :: new ( self . build_reduced_graph_external ( module. expect_extern ( ) ) )
2185+ } )
2186+ }
21722187 }
2173- & module. 0 . 0 . lazy_resolutions
21742188 }
21752189
21762190 fn resolution (
@@ -2924,13 +2938,6 @@ mod ref_mut {
29242938 CmRefCell ( RefCell :: new ( value) )
29252939 }
29262940
2927- #[ track_caller]
2928- // FIXME: this should be eliminated in the process of migration
2929- // to parallel name resolution.
2930- pub ( crate ) fn borrow_mut_unchecked ( & self ) -> RefMut < ' _ , T > {
2931- self . 0 . borrow_mut ( )
2932- }
2933-
29342941 #[ track_caller]
29352942 pub ( crate ) fn borrow_mut < ' ra , ' tcx > ( & self , r : & Resolver < ' ra , ' tcx > ) -> RefMut < ' _ , T > {
29362943 if r. assert_speculative {
0 commit comments