@@ -50,8 +50,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5050 StableHasher , StableHasherResult ,
5151 StableVec } ;
5252use arena:: { TypedArena , SyncDroplessArena } ;
53+ use rustc_data_structures:: cold_path;
5354use rustc_data_structures:: indexed_vec:: { Idx , IndexVec } ;
54- use rustc_data_structures:: sync:: { Lrc , Lock , WorkerLocal } ;
55+ use rustc_data_structures:: sync:: { Lrc , Lock , WorkerLocal , AtomicCell } ;
5556use std:: any:: Any ;
5657use std:: borrow:: Borrow ;
5758use std:: cmp:: Ordering ;
@@ -93,6 +94,8 @@ impl<'tcx> AllArenas<'tcx> {
9394/// Internal storage
9495#[ derive( Default ) ]
9596pub struct GlobalArenas < ' tcx > {
97+ pub hir_map : TypedArena < hir_map:: Map < ' tcx > > ,
98+
9699 // internings
97100 layout : TypedArena < LayoutDetails > ,
98101
@@ -1003,10 +1006,10 @@ impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
10031006}
10041007
10051008pub struct GlobalCtxt < ' tcx > {
1006- global_arenas : & ' tcx WorkerLocal < GlobalArenas < ' tcx > > ,
1009+ pub global_arenas : & ' tcx WorkerLocal < GlobalArenas < ' tcx > > ,
10071010 global_interners : CtxtInterners < ' tcx > ,
10081011
1009- cstore : & ' tcx CrateStoreDyn ,
1012+ pub ( crate ) cstore : & ' tcx CrateStoreDyn ,
10101013
10111014 pub sess : & ' tcx Session ,
10121015
@@ -1024,7 +1027,11 @@ pub struct GlobalCtxt<'tcx> {
10241027 /// Export map produced by name resolution.
10251028 export_map : FxHashMap < DefId , Lrc < Vec < Export > > > ,
10261029
1027- hir_map : hir_map:: Map < ' tcx > ,
1030+ pub hir_forest : hir:: map:: Forest ,
1031+
1032+ pub hir_defs : hir:: map:: Definitions ,
1033+
1034+ hir_map : AtomicCell < Option < & ' tcx hir_map:: Map < ' tcx > > > ,
10281035
10291036 /// A map from DefPathHash -> DefId. Includes DefIds from the local crate
10301037 /// as well as all upstream crates. Only populated in incremental mode.
@@ -1098,7 +1105,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
10981105
10991106 #[ inline( always) ]
11001107 pub fn hir ( self ) -> & ' a hir_map:: Map < ' gcx > {
1101- & self . hir_map
1108+ let value = self . hir_map . load ( ) ;
1109+ if unlikely ! ( value. is_none( ) ) {
1110+ // We can use `with_ignore` here because the hir map does its own tracking
1111+ cold_path ( || self . dep_graph . with_ignore ( || {
1112+ let map = self . hir_map ( LOCAL_CRATE ) ;
1113+ self . hir_map . store ( Some ( map) ) ;
1114+ map
1115+ } ) )
1116+ } else {
1117+ value. unwrap ( )
1118+ }
11021119 }
11031120
11041121 pub fn alloc_generics ( self , generics : ty:: Generics ) -> & ' gcx ty:: Generics {
@@ -1202,7 +1219,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12021219 extern_providers : ty:: query:: Providers < ' tcx > ,
12031220 arenas : & ' tcx AllArenas < ' tcx > ,
12041221 resolutions : ty:: Resolutions ,
1205- hir : hir_map:: Map < ' tcx > ,
1222+ hir_forest : hir:: map:: Forest ,
1223+ hir_defs : hir:: map:: Definitions ,
12061224 on_disk_query_result_cache : query:: OnDiskCache < ' tcx > ,
12071225 crate_name : & str ,
12081226 tx : mpsc:: Sender < Box < dyn Any + Send > > ,
@@ -1213,7 +1231,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12131231 } ) ;
12141232 let interners = CtxtInterners :: new ( & arenas. interner ) ;
12151233 let common_types = CommonTypes :: new ( & interners) ;
1216- let dep_graph = hir . dep_graph . clone ( ) ;
1234+ let dep_graph = hir_forest . dep_graph . clone ( ) ;
12171235 let max_cnum = cstore. crates_untracked ( ) . iter ( ) . map ( |c| c. as_usize ( ) ) . max ( ) . unwrap_or ( 0 ) ;
12181236 let mut providers = IndexVec :: from_elem_n ( extern_providers, max_cnum + 1 ) ;
12191237 providers[ LOCAL_CRATE ] = local_providers;
@@ -1229,7 +1247,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12291247 upstream_def_path_tables
12301248 . iter ( )
12311249 . map ( |& ( cnum, ref rc) | ( cnum, & * * rc) )
1232- . chain ( iter:: once ( ( LOCAL_CRATE , hir . definitions ( ) . def_path_table ( ) ) ) )
1250+ . chain ( iter:: once ( ( LOCAL_CRATE , hir_defs . def_path_table ( ) ) ) )
12331251 } ;
12341252
12351253 // Precompute the capacity of the hashmap so we don't have to
@@ -1252,7 +1270,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12521270
12531271 let mut trait_map: FxHashMap < _ , Lrc < FxHashMap < _ , _ > > > = FxHashMap :: default ( ) ;
12541272 for ( k, v) in resolutions. trait_map {
1255- let hir_id = hir . node_to_hir_id ( k) ;
1273+ let hir_id = hir_defs . node_to_hir_id ( k) ;
12561274 let map = trait_map. entry ( hir_id. owner ) . or_default ( ) ;
12571275 Lrc :: get_mut ( map) . unwrap ( )
12581276 . insert ( hir_id. local_id ,
@@ -1271,23 +1289,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12711289 ( k, Lrc :: new ( v) )
12721290 } ) . collect ( ) ,
12731291 freevars : resolutions. freevars . into_iter ( ) . map ( |( k, v) | {
1274- ( hir . local_def_id ( k) , Lrc :: new ( v) )
1292+ ( hir_defs . local_def_id ( k) , Lrc :: new ( v) )
12751293 } ) . collect ( ) ,
12761294 maybe_unused_trait_imports :
12771295 resolutions. maybe_unused_trait_imports
12781296 . into_iter ( )
1279- . map ( |id| hir . local_def_id ( id) )
1297+ . map ( |id| hir_defs . local_def_id ( id) )
12801298 . collect ( ) ,
12811299 maybe_unused_extern_crates :
12821300 resolutions. maybe_unused_extern_crates
12831301 . into_iter ( )
1284- . map ( |( id, sp) | ( hir . local_def_id ( id) , sp) )
1302+ . map ( |( id, sp) | ( hir_defs . local_def_id ( id) , sp) )
12851303 . collect ( ) ,
12861304 glob_map : resolutions. glob_map . into_iter ( ) . map ( |( id, names) | {
1287- ( hir . local_def_id ( id) , names)
1305+ ( hir_defs . local_def_id ( id) , names)
12881306 } ) . collect ( ) ,
12891307 extern_prelude : resolutions. extern_prelude ,
1290- hir_map : hir,
1308+ hir_forest,
1309+ hir_defs,
1310+ hir_map : AtomicCell :: new ( None ) ,
12911311 def_path_hash_to_def_id,
12921312 queries : query:: Queries :: new (
12931313 providers,
@@ -1391,7 +1411,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
13911411 #[ inline]
13921412 pub fn def_path_hash ( self , def_id : DefId ) -> hir_map:: DefPathHash {
13931413 if def_id. is_local ( ) {
1394- self . hir ( ) . definitions ( ) . def_path_hash ( def_id. index )
1414+ // This is used when creating dep nodes, which happens when executing queries,
1415+ // so we can't use hir() here
1416+ self . hir_defs . def_path_hash ( def_id. index )
13951417 } else {
13961418 self . cstore . def_path_hash ( def_id)
13971419 }
@@ -1430,12 +1452,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
14301452
14311453 #[ inline( always) ]
14321454 pub fn create_stable_hashing_context ( self ) -> StableHashingContext < ' a > {
1433- let krate = self . gcx . hir_map . forest . untracked_krate ( ) ;
1434-
1435- StableHashingContext :: new ( self . sess ,
1436- krate,
1437- self . hir ( ) . definitions ( ) ,
1438- self . cstore )
1455+ // This is used when executing queries. Also used when dealing with query cycles
1456+ StableHashingContext :: new (
1457+ self . sess ,
1458+ self . hir_forest . untracked_krate ( ) ,
1459+ & self . hir_defs ,
1460+ self . cstore
1461+ )
14391462 }
14401463
14411464 // This method makes sure that we have a DepNode and a Fingerprint for
0 commit comments