@@ -54,8 +54,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5454 StableHasher , StableHasherResult ,
5555 StableVec } ;
5656use arena:: SyncDroplessArena ;
57+ use rustc_data_structures:: cold_path;
5758use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
58- use rustc_data_structures:: sync:: { Lrc , Lock , WorkerLocal } ;
59+ use rustc_data_structures:: sync:: { Lrc , Lock , WorkerLocal , AtomicCell } ;
5960use std:: any:: Any ;
6061use std:: borrow:: Borrow ;
6162use std:: cmp:: Ordering ;
@@ -1035,7 +1036,7 @@ pub struct GlobalCtxt<'tcx> {
10351036 global_interners : CtxtInterners < ' tcx > ,
10361037 local_interners : CtxtInterners < ' tcx > ,
10371038
1038- cstore : & ' tcx CrateStoreDyn ,
1039+ pub ( crate ) cstore : & ' tcx CrateStoreDyn ,
10391040
10401041 pub sess : & ' tcx Session ,
10411042
@@ -1062,7 +1063,11 @@ pub struct GlobalCtxt<'tcx> {
10621063 /// Export map produced by name resolution.
10631064 export_map : FxHashMap < DefId , Vec < Export < hir:: HirId > > > ,
10641065
1065- hir_map : hir_map:: Map < ' tcx > ,
1066+ pub hir_forest : hir:: map:: Forest ,
1067+
1068+ pub hir_defs : hir:: map:: Definitions ,
1069+
1070+ hir_map : AtomicCell < Option < & ' tcx hir_map:: Map < ' tcx > > > ,
10661071
10671072 /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
10681073 /// as well as all upstream crates. Only populated in incremental mode.
@@ -1131,7 +1136,17 @@ impl<'tcx> TyCtxt<'tcx> {
11311136
11321137 #[ inline( always) ]
11331138 pub fn hir ( self ) -> & ' tcx hir_map:: Map < ' tcx > {
1134- & self . hir_map
1139+ let value = self . hir_map . load ( ) ;
1140+ if unlikely ! ( value. is_none( ) ) {
1141+ // We can use `with_ignore` here because the hir map does its own tracking
1142+ cold_path ( || self . dep_graph . with_ignore ( || {
1143+ let map = self . hir_map ( LOCAL_CRATE ) ;
1144+ self . hir_map . store ( Some ( map) ) ;
1145+ map
1146+ } ) )
1147+ } else {
1148+ value. unwrap ( )
1149+ }
11351150 }
11361151
11371152 pub fn alloc_steal_mir ( self , mir : Body < ' tcx > ) -> & ' tcx Steal < Body < ' tcx > > {
@@ -1221,7 +1236,8 @@ impl<'tcx> TyCtxt<'tcx> {
12211236 extern_providers : ty:: query:: Providers < ' tcx > ,
12221237 arenas : & ' tcx AllArenas ,
12231238 resolutions : ty:: Resolutions ,
1224- hir : hir_map:: Map < ' tcx > ,
1239+ hir_forest : hir:: map:: Forest ,
1240+ hir_defs : hir:: map:: Definitions ,
12251241 on_disk_query_result_cache : query:: OnDiskCache < ' tcx > ,
12261242 crate_name : & str ,
12271243 tx : mpsc:: Sender < Box < dyn Any + Send > > ,
@@ -1241,7 +1257,7 @@ impl<'tcx> TyCtxt<'tcx> {
12411257 let common_types = CommonTypes :: new ( & interners) ;
12421258 let common_lifetimes = CommonLifetimes :: new ( & interners) ;
12431259 let common_consts = CommonConsts :: new ( & interners, & common_types) ;
1244- let dep_graph = hir . dep_graph . clone ( ) ;
1260+ let dep_graph = hir_forest . dep_graph . clone ( ) ;
12451261 let max_cnum = cstore. crates_untracked ( ) . iter ( ) . map ( |c| c. as_usize ( ) ) . max ( ) . unwrap_or ( 0 ) ;
12461262 let mut providers = IndexVec :: from_elem_n ( extern_providers, max_cnum + 1 ) ;
12471263 providers[ LOCAL_CRATE ] = local_providers;
@@ -1257,7 +1273,7 @@ impl<'tcx> TyCtxt<'tcx> {
12571273 upstream_def_path_tables
12581274 . iter ( )
12591275 . map ( |& ( cnum, ref rc) | ( cnum, & * * rc) )
1260- . chain ( iter:: once ( ( LOCAL_CRATE , hir . definitions ( ) . def_path_table ( ) ) ) )
1276+ . chain ( iter:: once ( ( LOCAL_CRATE , hir_defs . def_path_table ( ) ) ) )
12611277 } ;
12621278
12631279 // Precompute the capacity of the hashmap so we don't have to
@@ -1280,7 +1296,7 @@ impl<'tcx> TyCtxt<'tcx> {
12801296
12811297 let mut trait_map: FxHashMap < _ , FxHashMap < _ , _ > > = FxHashMap :: default ( ) ;
12821298 for ( k, v) in resolutions. trait_map {
1283- let hir_id = hir . node_to_hir_id ( k) ;
1299+ let hir_id = hir_defs . node_to_hir_id ( k) ;
12841300 let map = trait_map. entry ( hir_id. owner ) . or_default ( ) ;
12851301 map. insert ( hir_id. local_id , StableVec :: new ( v) ) ;
12861302 }
@@ -1299,25 +1315,27 @@ impl<'tcx> TyCtxt<'tcx> {
12991315 trait_map,
13001316 export_map : resolutions. export_map . into_iter ( ) . map ( |( k, v) | {
13011317 let exports: Vec < _ > = v. into_iter ( ) . map ( |e| {
1302- e. map_id ( |id| hir . node_to_hir_id ( id) )
1318+ e. map_id ( |id| hir_defs . node_to_hir_id ( id) )
13031319 } ) . collect ( ) ;
13041320 ( k, exports)
13051321 } ) . collect ( ) ,
13061322 maybe_unused_trait_imports :
13071323 resolutions. maybe_unused_trait_imports
13081324 . into_iter ( )
1309- . map ( |id| hir . local_def_id ( id) )
1325+ . map ( |id| hir_defs . local_def_id ( id) )
13101326 . collect ( ) ,
13111327 maybe_unused_extern_crates :
13121328 resolutions. maybe_unused_extern_crates
13131329 . into_iter ( )
1314- . map ( |( id, sp) | ( hir . local_def_id ( id) , sp) )
1330+ . map ( |( id, sp) | ( hir_defs . local_def_id ( id) , sp) )
13151331 . collect ( ) ,
13161332 glob_map : resolutions. glob_map . into_iter ( ) . map ( |( id, names) | {
1317- ( hir . local_def_id ( id) , names)
1333+ ( hir_defs . local_def_id ( id) , names)
13181334 } ) . collect ( ) ,
13191335 extern_prelude : resolutions. extern_prelude ,
1320- hir_map : hir,
1336+ hir_forest,
1337+ hir_defs,
1338+ hir_map : AtomicCell :: new ( None ) ,
13211339 def_path_hash_to_def_id,
13221340 queries : query:: Queries :: new (
13231341 providers,
@@ -1431,7 +1449,9 @@ impl<'tcx> TyCtxt<'tcx> {
14311449 #[ inline]
14321450 pub fn def_path_hash ( self , def_id : DefId ) -> hir_map:: DefPathHash {
14331451 if def_id. is_local ( ) {
1434- self . hir ( ) . definitions ( ) . def_path_hash ( def_id. index )
1452+ // This is used when creating dep nodes, which happens when executing queries,
1453+ // so we can't use hir() here
1454+ self . hir_defs . def_path_hash ( def_id. index )
14351455 } else {
14361456 self . cstore . def_path_hash ( def_id)
14371457 }
@@ -1470,12 +1490,13 @@ impl<'tcx> TyCtxt<'tcx> {
14701490
14711491 #[ inline( always) ]
14721492 pub fn create_stable_hashing_context ( self ) -> StableHashingContext < ' tcx > {
1473- let krate = self . gcx . hir_map . forest . untracked_krate ( ) ;
1474-
1475- StableHashingContext :: new ( self . sess ,
1476- krate,
1477- self . hir ( ) . definitions ( ) ,
1478- self . cstore )
1493+ // This is used when executing queries. Also used when dealing with query cycles
1494+ StableHashingContext :: new (
1495+ self . sess ,
1496+ self . hir_forest . untracked_krate ( ) ,
1497+ & self . hir_defs ,
1498+ self . cstore
1499+ )
14791500 }
14801501
14811502 // This method makes sure that we have a DepNode and a Fingerprint for
0 commit comments