@@ -54,8 +54,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
54
54
StableHasher , StableHasherResult ,
55
55
StableVec } ;
56
56
use arena:: SyncDroplessArena ;
57
+ use rustc_data_structures:: cold_path;
57
58
use 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 } ;
59
60
use std:: any:: Any ;
60
61
use std:: borrow:: Borrow ;
61
62
use std:: cmp:: Ordering ;
@@ -1035,7 +1036,7 @@ pub struct GlobalCtxt<'tcx> {
1035
1036
global_interners : CtxtInterners < ' tcx > ,
1036
1037
local_interners : CtxtInterners < ' tcx > ,
1037
1038
1038
- cstore : & ' tcx CrateStoreDyn ,
1039
+ pub ( crate ) cstore : & ' tcx CrateStoreDyn ,
1039
1040
1040
1041
pub sess : & ' tcx Session ,
1041
1042
@@ -1062,7 +1063,11 @@ pub struct GlobalCtxt<'tcx> {
1062
1063
/// Export map produced by name resolution.
1063
1064
export_map : FxHashMap < DefId , Vec < Export < hir:: HirId > > > ,
1064
1065
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 > > > ,
1066
1071
1067
1072
/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
1068
1073
/// as well as all upstream crates. Only populated in incremental mode.
@@ -1131,7 +1136,17 @@ impl<'tcx> TyCtxt<'tcx> {
1131
1136
1132
1137
#[ inline( always) ]
1133
1138
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
+ }
1135
1150
}
1136
1151
1137
1152
pub fn alloc_steal_mir ( self , mir : Body < ' tcx > ) -> & ' tcx Steal < Body < ' tcx > > {
@@ -1221,7 +1236,8 @@ impl<'tcx> TyCtxt<'tcx> {
1221
1236
extern_providers : ty:: query:: Providers < ' tcx > ,
1222
1237
arenas : & ' tcx AllArenas ,
1223
1238
resolutions : ty:: Resolutions ,
1224
- hir : hir_map:: Map < ' tcx > ,
1239
+ hir_forest : hir:: map:: Forest ,
1240
+ hir_defs : hir:: map:: Definitions ,
1225
1241
on_disk_query_result_cache : query:: OnDiskCache < ' tcx > ,
1226
1242
crate_name : & str ,
1227
1243
tx : mpsc:: Sender < Box < dyn Any + Send > > ,
@@ -1241,7 +1257,7 @@ impl<'tcx> TyCtxt<'tcx> {
1241
1257
let common_types = CommonTypes :: new ( & interners) ;
1242
1258
let common_lifetimes = CommonLifetimes :: new ( & interners) ;
1243
1259
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 ( ) ;
1245
1261
let max_cnum = cstore. crates_untracked ( ) . iter ( ) . map ( |c| c. as_usize ( ) ) . max ( ) . unwrap_or ( 0 ) ;
1246
1262
let mut providers = IndexVec :: from_elem_n ( extern_providers, max_cnum + 1 ) ;
1247
1263
providers[ LOCAL_CRATE ] = local_providers;
@@ -1257,7 +1273,7 @@ impl<'tcx> TyCtxt<'tcx> {
1257
1273
upstream_def_path_tables
1258
1274
. iter ( )
1259
1275
. 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 ( ) ) ) )
1261
1277
} ;
1262
1278
1263
1279
// Precompute the capacity of the hashmap so we don't have to
@@ -1280,7 +1296,7 @@ impl<'tcx> TyCtxt<'tcx> {
1280
1296
1281
1297
let mut trait_map: FxHashMap < _ , FxHashMap < _ , _ > > = FxHashMap :: default ( ) ;
1282
1298
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) ;
1284
1300
let map = trait_map. entry ( hir_id. owner ) . or_default ( ) ;
1285
1301
map. insert ( hir_id. local_id , StableVec :: new ( v) ) ;
1286
1302
}
@@ -1299,25 +1315,27 @@ impl<'tcx> TyCtxt<'tcx> {
1299
1315
trait_map,
1300
1316
export_map : resolutions. export_map . into_iter ( ) . map ( |( k, v) | {
1301
1317
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) )
1303
1319
} ) . collect ( ) ;
1304
1320
( k, exports)
1305
1321
} ) . collect ( ) ,
1306
1322
maybe_unused_trait_imports :
1307
1323
resolutions. maybe_unused_trait_imports
1308
1324
. into_iter ( )
1309
- . map ( |id| hir . local_def_id ( id) )
1325
+ . map ( |id| hir_defs . local_def_id ( id) )
1310
1326
. collect ( ) ,
1311
1327
maybe_unused_extern_crates :
1312
1328
resolutions. maybe_unused_extern_crates
1313
1329
. into_iter ( )
1314
- . map ( |( id, sp) | ( hir . local_def_id ( id) , sp) )
1330
+ . map ( |( id, sp) | ( hir_defs . local_def_id ( id) , sp) )
1315
1331
. collect ( ) ,
1316
1332
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)
1318
1334
} ) . collect ( ) ,
1319
1335
extern_prelude : resolutions. extern_prelude ,
1320
- hir_map : hir,
1336
+ hir_forest,
1337
+ hir_defs,
1338
+ hir_map : AtomicCell :: new ( None ) ,
1321
1339
def_path_hash_to_def_id,
1322
1340
queries : query:: Queries :: new (
1323
1341
providers,
@@ -1431,7 +1449,9 @@ impl<'tcx> TyCtxt<'tcx> {
1431
1449
#[ inline]
1432
1450
pub fn def_path_hash ( self , def_id : DefId ) -> hir_map:: DefPathHash {
1433
1451
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 )
1435
1455
} else {
1436
1456
self . cstore . def_path_hash ( def_id)
1437
1457
}
@@ -1470,12 +1490,13 @@ impl<'tcx> TyCtxt<'tcx> {
1470
1490
1471
1491
#[ inline( always) ]
1472
1492
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
+ )
1479
1500
}
1480
1501
1481
1502
// This method makes sure that we have a DepNode and a Fingerprint for
0 commit comments