@@ -52,8 +52,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5252 StableHasher , StableHasherResult ,
5353 StableVec } ;
5454use arena:: SyncDroplessArena ;
55+ use rustc_data_structures:: cold_path;
5556use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
56- use rustc_data_structures:: sync:: { Lrc , Lock , WorkerLocal } ;
57+ use rustc_data_structures:: sync:: { Lrc , Lock , WorkerLocal , AtomicCell } ;
5758use std:: any:: Any ;
5859use std:: borrow:: Borrow ;
5960use std:: cmp:: Ordering ;
@@ -990,7 +991,7 @@ pub struct GlobalCtxt<'tcx> {
990991
991992 interners : CtxtInterners < ' tcx > ,
992993
993- cstore : & ' tcx CrateStoreDyn ,
994+ pub ( crate ) cstore : & ' tcx CrateStoreDyn ,
994995
995996 pub sess : & ' tcx Session ,
996997
@@ -1017,7 +1018,11 @@ pub struct GlobalCtxt<'tcx> {
10171018 /// Export map produced by name resolution.
10181019 export_map : FxHashMap < DefId , Vec < Export < hir:: HirId > > > ,
10191020
1020- hir_map : hir_map:: Map < ' tcx > ,
1021+ pub hir_forest : hir:: map:: Forest ,
1022+
1023+ pub hir_defs : hir:: map:: Definitions ,
1024+
1025+ hir_map : AtomicCell < Option < & ' tcx hir_map:: Map < ' tcx > > > ,
10211026
10221027 /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
10231028 /// as well as all upstream crates. Only populated in incremental mode.
@@ -1084,7 +1089,17 @@ impl<'tcx> TyCtxt<'tcx> {
10841089
10851090 #[ inline( always) ]
10861091 pub fn hir ( self ) -> & ' tcx hir_map:: Map < ' tcx > {
1087- & self . hir_map
1092+ let value = self . hir_map . load ( ) ;
1093+ if unlikely ! ( value. is_none( ) ) {
1094+ // We can use `with_ignore` here because the hir map does its own tracking
1095+ cold_path ( || self . dep_graph . with_ignore ( || {
1096+ let map = self . hir_map ( LOCAL_CRATE ) ;
1097+ self . hir_map . store ( Some ( map) ) ;
1098+ map
1099+ } ) )
1100+ } else {
1101+ value. unwrap ( )
1102+ }
10881103 }
10891104
10901105 pub fn alloc_steal_mir ( self , mir : Body < ' tcx > ) -> & ' tcx Steal < Body < ' tcx > > {
@@ -1169,7 +1184,8 @@ impl<'tcx> TyCtxt<'tcx> {
11691184 extern_providers : ty:: query:: Providers < ' tcx > ,
11701185 arenas : & ' tcx AllArenas ,
11711186 resolutions : ty:: Resolutions ,
1172- hir : hir_map:: Map < ' tcx > ,
1187+ hir_forest : hir:: map:: Forest ,
1188+ hir_defs : hir:: map:: Definitions ,
11731189 on_disk_query_result_cache : query:: OnDiskCache < ' tcx > ,
11741190 crate_name : & str ,
11751191 tx : mpsc:: Sender < Box < dyn Any + Send > > ,
@@ -1188,7 +1204,7 @@ impl<'tcx> TyCtxt<'tcx> {
11881204 let common_types = CommonTypes :: new ( & interners) ;
11891205 let common_lifetimes = CommonLifetimes :: new ( & interners) ;
11901206 let common_consts = CommonConsts :: new ( & interners, & common_types) ;
1191- let dep_graph = hir . dep_graph . clone ( ) ;
1207+ let dep_graph = hir_forest . dep_graph . clone ( ) ;
11921208 let max_cnum = cstore. crates_untracked ( ) . iter ( ) . map ( |c| c. as_usize ( ) ) . max ( ) . unwrap_or ( 0 ) ;
11931209 let mut providers = IndexVec :: from_elem_n ( extern_providers, max_cnum + 1 ) ;
11941210 providers[ LOCAL_CRATE ] = local_providers;
@@ -1204,7 +1220,7 @@ impl<'tcx> TyCtxt<'tcx> {
12041220 upstream_def_path_tables
12051221 . iter ( )
12061222 . map ( |& ( cnum, ref rc) | ( cnum, & * * rc) )
1207- . chain ( iter:: once ( ( LOCAL_CRATE , hir . definitions ( ) . def_path_table ( ) ) ) )
1223+ . chain ( iter:: once ( ( LOCAL_CRATE , hir_defs . def_path_table ( ) ) ) )
12081224 } ;
12091225
12101226 // Precompute the capacity of the hashmap so we don't have to
@@ -1227,7 +1243,7 @@ impl<'tcx> TyCtxt<'tcx> {
12271243
12281244 let mut trait_map: FxHashMap < _ , FxHashMap < _ , _ > > = FxHashMap :: default ( ) ;
12291245 for ( k, v) in resolutions. trait_map {
1230- let hir_id = hir . node_to_hir_id ( k) ;
1246+ let hir_id = hir_defs . node_to_hir_id ( k) ;
12311247 let map = trait_map. entry ( hir_id. owner ) . or_default ( ) ;
12321248 map. insert ( hir_id. local_id , StableVec :: new ( v) ) ;
12331249 }
@@ -1245,25 +1261,27 @@ impl<'tcx> TyCtxt<'tcx> {
12451261 trait_map,
12461262 export_map : resolutions. export_map . into_iter ( ) . map ( |( k, v) | {
12471263 let exports: Vec < _ > = v. into_iter ( ) . map ( |e| {
1248- e. map_id ( |id| hir . node_to_hir_id ( id) )
1264+ e. map_id ( |id| hir_defs . node_to_hir_id ( id) )
12491265 } ) . collect ( ) ;
12501266 ( k, exports)
12511267 } ) . collect ( ) ,
12521268 maybe_unused_trait_imports :
12531269 resolutions. maybe_unused_trait_imports
12541270 . into_iter ( )
1255- . map ( |id| hir . local_def_id_from_node_id ( id) )
1271+ . map ( |id| hir_defs . local_def_id ( id) )
12561272 . collect ( ) ,
12571273 maybe_unused_extern_crates :
12581274 resolutions. maybe_unused_extern_crates
12591275 . into_iter ( )
1260- . map ( |( id, sp) | ( hir . local_def_id_from_node_id ( id) , sp) )
1276+ . map ( |( id, sp) | ( hir_defs . local_def_id ( id) , sp) )
12611277 . collect ( ) ,
12621278 glob_map : resolutions. glob_map . into_iter ( ) . map ( |( id, names) | {
1263- ( hir . local_def_id_from_node_id ( id) , names)
1279+ ( hir_defs . local_def_id ( id) , names)
12641280 } ) . collect ( ) ,
12651281 extern_prelude : resolutions. extern_prelude ,
1266- hir_map : hir,
1282+ hir_forest,
1283+ hir_defs,
1284+ hir_map : AtomicCell :: new ( None ) ,
12671285 def_path_hash_to_def_id,
12681286 queries : query:: Queries :: new (
12691287 providers,
@@ -1377,7 +1395,9 @@ impl<'tcx> TyCtxt<'tcx> {
13771395 #[ inline]
13781396 pub fn def_path_hash ( self , def_id : DefId ) -> hir_map:: DefPathHash {
13791397 if def_id. is_local ( ) {
1380- self . hir ( ) . definitions ( ) . def_path_hash ( def_id. index )
1398+ // This is used when creating dep nodes, which happens when executing queries,
1399+ // so we can't use hir() here
1400+ self . hir_defs . def_path_hash ( def_id. index )
13811401 } else {
13821402 self . cstore . def_path_hash ( def_id)
13831403 }
@@ -1416,12 +1436,13 @@ impl<'tcx> TyCtxt<'tcx> {
14161436
14171437 #[ inline( always) ]
14181438 pub fn create_stable_hashing_context ( self ) -> StableHashingContext < ' tcx > {
1419- let krate = self . gcx . hir_map . forest . untracked_krate ( ) ;
1420-
1421- StableHashingContext :: new ( self . sess ,
1422- krate,
1423- self . hir ( ) . definitions ( ) ,
1424- self . cstore )
1439+ // This is used when executing queries. Also used when dealing with query cycles
1440+ StableHashingContext :: new (
1441+ self . sess ,
1442+ self . hir_forest . untracked_krate ( ) ,
1443+ & self . hir_defs ,
1444+ self . cstore
1445+ )
14251446 }
14261447
14271448 // This method makes sure that we have a DepNode and a Fingerprint for
0 commit comments