@@ -52,8 +52,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
52
52
StableHasher , StableHasherResult ,
53
53
StableVec } ;
54
54
use arena:: SyncDroplessArena ;
55
+ use rustc_data_structures:: cold_path;
55
56
use 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 } ;
57
58
use std:: any:: Any ;
58
59
use std:: borrow:: Borrow ;
59
60
use std:: cmp:: Ordering ;
@@ -990,7 +991,7 @@ pub struct GlobalCtxt<'tcx> {
990
991
991
992
interners : CtxtInterners < ' tcx > ,
992
993
993
- cstore : & ' tcx CrateStoreDyn ,
994
+ pub ( crate ) cstore : & ' tcx CrateStoreDyn ,
994
995
995
996
pub sess : & ' tcx Session ,
996
997
@@ -1017,7 +1018,11 @@ pub struct GlobalCtxt<'tcx> {
1017
1018
/// Export map produced by name resolution.
1018
1019
export_map : FxHashMap < DefId , Vec < Export < hir:: HirId > > > ,
1019
1020
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 > > > ,
1021
1026
1022
1027
/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
1023
1028
/// as well as all upstream crates. Only populated in incremental mode.
@@ -1084,7 +1089,17 @@ impl<'tcx> TyCtxt<'tcx> {
1084
1089
1085
1090
#[ inline( always) ]
1086
1091
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
+ }
1088
1103
}
1089
1104
1090
1105
pub fn alloc_steal_mir ( self , mir : Body < ' tcx > ) -> & ' tcx Steal < Body < ' tcx > > {
@@ -1169,7 +1184,8 @@ impl<'tcx> TyCtxt<'tcx> {
1169
1184
extern_providers : ty:: query:: Providers < ' tcx > ,
1170
1185
arenas : & ' tcx AllArenas ,
1171
1186
resolutions : ty:: Resolutions ,
1172
- hir : hir_map:: Map < ' tcx > ,
1187
+ hir_forest : hir:: map:: Forest ,
1188
+ hir_defs : hir:: map:: Definitions ,
1173
1189
on_disk_query_result_cache : query:: OnDiskCache < ' tcx > ,
1174
1190
crate_name : & str ,
1175
1191
tx : mpsc:: Sender < Box < dyn Any + Send > > ,
@@ -1188,7 +1204,7 @@ impl<'tcx> TyCtxt<'tcx> {
1188
1204
let common_types = CommonTypes :: new ( & interners) ;
1189
1205
let common_lifetimes = CommonLifetimes :: new ( & interners) ;
1190
1206
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 ( ) ;
1192
1208
let max_cnum = cstore. crates_untracked ( ) . iter ( ) . map ( |c| c. as_usize ( ) ) . max ( ) . unwrap_or ( 0 ) ;
1193
1209
let mut providers = IndexVec :: from_elem_n ( extern_providers, max_cnum + 1 ) ;
1194
1210
providers[ LOCAL_CRATE ] = local_providers;
@@ -1204,7 +1220,7 @@ impl<'tcx> TyCtxt<'tcx> {
1204
1220
upstream_def_path_tables
1205
1221
. iter ( )
1206
1222
. 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 ( ) ) ) )
1208
1224
} ;
1209
1225
1210
1226
// Precompute the capacity of the hashmap so we don't have to
@@ -1227,7 +1243,7 @@ impl<'tcx> TyCtxt<'tcx> {
1227
1243
1228
1244
let mut trait_map: FxHashMap < _ , FxHashMap < _ , _ > > = FxHashMap :: default ( ) ;
1229
1245
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) ;
1231
1247
let map = trait_map. entry ( hir_id. owner ) . or_default ( ) ;
1232
1248
map. insert ( hir_id. local_id , StableVec :: new ( v) ) ;
1233
1249
}
@@ -1245,25 +1261,27 @@ impl<'tcx> TyCtxt<'tcx> {
1245
1261
trait_map,
1246
1262
export_map : resolutions. export_map . into_iter ( ) . map ( |( k, v) | {
1247
1263
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) )
1249
1265
} ) . collect ( ) ;
1250
1266
( k, exports)
1251
1267
} ) . collect ( ) ,
1252
1268
maybe_unused_trait_imports :
1253
1269
resolutions. maybe_unused_trait_imports
1254
1270
. into_iter ( )
1255
- . map ( |id| hir . local_def_id_from_node_id ( id) )
1271
+ . map ( |id| hir_defs . local_def_id ( id) )
1256
1272
. collect ( ) ,
1257
1273
maybe_unused_extern_crates :
1258
1274
resolutions. maybe_unused_extern_crates
1259
1275
. 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) )
1261
1277
. collect ( ) ,
1262
1278
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)
1264
1280
} ) . collect ( ) ,
1265
1281
extern_prelude : resolutions. extern_prelude ,
1266
- hir_map : hir,
1282
+ hir_forest,
1283
+ hir_defs,
1284
+ hir_map : AtomicCell :: new ( None ) ,
1267
1285
def_path_hash_to_def_id,
1268
1286
queries : query:: Queries :: new (
1269
1287
providers,
@@ -1377,7 +1395,9 @@ impl<'tcx> TyCtxt<'tcx> {
1377
1395
#[ inline]
1378
1396
pub fn def_path_hash ( self , def_id : DefId ) -> hir_map:: DefPathHash {
1379
1397
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 )
1381
1401
} else {
1382
1402
self . cstore . def_path_hash ( def_id)
1383
1403
}
@@ -1416,12 +1436,13 @@ impl<'tcx> TyCtxt<'tcx> {
1416
1436
1417
1437
#[ inline( always) ]
1418
1438
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
+ )
1425
1446
}
1426
1447
1427
1448
// This method makes sure that we have a DepNode and a Fingerprint for
0 commit comments