@@ -50,8 +50,9 @@ use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
50
50
StableHasher , StableHasherResult ,
51
51
StableVec } ;
52
52
use arena:: { TypedArena , SyncDroplessArena } ;
53
+ use rustc_data_structures:: cold_path;
53
54
use 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 } ;
55
56
use std:: any:: Any ;
56
57
use std:: borrow:: Borrow ;
57
58
use std:: cmp:: Ordering ;
@@ -93,6 +94,8 @@ impl<'tcx> AllArenas<'tcx> {
93
94
/// Internal storage
94
95
#[ derive( Default ) ]
95
96
pub struct GlobalArenas < ' tcx > {
97
+ pub hir_map : TypedArena < hir_map:: Map < ' tcx > > ,
98
+
96
99
// internings
97
100
layout : TypedArena < LayoutDetails > ,
98
101
@@ -990,10 +993,10 @@ impl<'gcx> Deref for TyCtxt<'_, 'gcx, '_> {
990
993
}
991
994
992
995
pub struct GlobalCtxt < ' tcx > {
993
- global_arenas : & ' tcx WorkerLocal < GlobalArenas < ' tcx > > ,
996
+ pub global_arenas : & ' tcx WorkerLocal < GlobalArenas < ' tcx > > ,
994
997
global_interners : CtxtInterners < ' tcx > ,
995
998
996
- cstore : & ' tcx CrateStoreDyn ,
999
+ pub ( crate ) cstore : & ' tcx CrateStoreDyn ,
997
1000
998
1001
pub sess : & ' tcx Session ,
999
1002
@@ -1011,7 +1014,11 @@ pub struct GlobalCtxt<'tcx> {
1011
1014
/// Export map produced by name resolution.
1012
1015
export_map : FxHashMap < DefId , Lrc < Vec < Export > > > ,
1013
1016
1014
- hir_map : hir_map:: Map < ' tcx > ,
1017
+ pub hir_forest : hir:: map:: Forest ,
1018
+
1019
+ pub hir_defs : hir:: map:: Definitions ,
1020
+
1021
+ hir_map : AtomicCell < Option < & ' tcx hir_map:: Map < ' tcx > > > ,
1015
1022
1016
1023
/// A map from DefPathHash -> DefId. Includes DefIds from the local crate
1017
1024
/// as well as all upstream crates. Only populated in incremental mode.
@@ -1085,7 +1092,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1085
1092
1086
1093
#[ inline( always) ]
1087
1094
pub fn hir ( self ) -> & ' a hir_map:: Map < ' gcx > {
1088
- & self . hir_map
1095
+ let value = self . hir_map . load ( ) ;
1096
+ if unlikely ! ( value. is_none( ) ) {
1097
+ cold_path ( || {
1098
+ let map = self . hir_map ( LOCAL_CRATE ) ;
1099
+ self . hir_map . store ( Some ( map) ) ;
1100
+ map
1101
+ } )
1102
+ } else {
1103
+ value. unwrap ( )
1104
+ }
1089
1105
}
1090
1106
1091
1107
pub fn alloc_generics ( self , generics : ty:: Generics ) -> & ' gcx ty:: Generics {
@@ -1189,7 +1205,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1189
1205
extern_providers : ty:: query:: Providers < ' tcx > ,
1190
1206
arenas : & ' tcx AllArenas < ' tcx > ,
1191
1207
resolutions : ty:: Resolutions ,
1192
- hir : hir_map:: Map < ' tcx > ,
1208
+ hir_forest : hir:: map:: Forest ,
1209
+ hir_defs : hir:: map:: Definitions ,
1193
1210
on_disk_query_result_cache : query:: OnDiskCache < ' tcx > ,
1194
1211
crate_name : & str ,
1195
1212
tx : mpsc:: Sender < Box < dyn Any + Send > > ,
@@ -1200,7 +1217,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1200
1217
} ) ;
1201
1218
let interners = CtxtInterners :: new ( & arenas. interner ) ;
1202
1219
let common_types = CommonTypes :: new ( & interners) ;
1203
- let dep_graph = hir . dep_graph . clone ( ) ;
1220
+ let dep_graph = hir_forest . dep_graph . clone ( ) ;
1204
1221
let max_cnum = cstore. crates_untracked ( ) . iter ( ) . map ( |c| c. as_usize ( ) ) . max ( ) . unwrap_or ( 0 ) ;
1205
1222
let mut providers = IndexVec :: from_elem_n ( extern_providers, max_cnum + 1 ) ;
1206
1223
providers[ LOCAL_CRATE ] = local_providers;
@@ -1216,7 +1233,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1216
1233
upstream_def_path_tables
1217
1234
. iter ( )
1218
1235
. map ( |& ( cnum, ref rc) | ( cnum, & * * rc) )
1219
- . chain ( iter:: once ( ( LOCAL_CRATE , hir . definitions ( ) . def_path_table ( ) ) ) )
1236
+ . chain ( iter:: once ( ( LOCAL_CRATE , hir_defs . def_path_table ( ) ) ) )
1220
1237
} ;
1221
1238
1222
1239
// Precompute the capacity of the hashmap so we don't have to
@@ -1239,7 +1256,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1239
1256
1240
1257
let mut trait_map: FxHashMap < _ , Lrc < FxHashMap < _ , _ > > > = FxHashMap :: default ( ) ;
1241
1258
for ( k, v) in resolutions. trait_map {
1242
- let hir_id = hir . node_to_hir_id ( k) ;
1259
+ let hir_id = hir_defs . node_to_hir_id ( k) ;
1243
1260
let map = trait_map. entry ( hir_id. owner ) . or_default ( ) ;
1244
1261
Lrc :: get_mut ( map) . unwrap ( )
1245
1262
. insert ( hir_id. local_id ,
@@ -1258,23 +1275,25 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1258
1275
( k, Lrc :: new ( v) )
1259
1276
} ) . collect ( ) ,
1260
1277
freevars : resolutions. freevars . into_iter ( ) . map ( |( k, v) | {
1261
- ( hir . local_def_id ( k) , Lrc :: new ( v) )
1278
+ ( hir_defs . local_def_id ( k) , Lrc :: new ( v) )
1262
1279
} ) . collect ( ) ,
1263
1280
maybe_unused_trait_imports :
1264
1281
resolutions. maybe_unused_trait_imports
1265
1282
. into_iter ( )
1266
- . map ( |id| hir . local_def_id ( id) )
1283
+ . map ( |id| hir_defs . local_def_id ( id) )
1267
1284
. collect ( ) ,
1268
1285
maybe_unused_extern_crates :
1269
1286
resolutions. maybe_unused_extern_crates
1270
1287
. into_iter ( )
1271
- . map ( |( id, sp) | ( hir . local_def_id ( id) , sp) )
1288
+ . map ( |( id, sp) | ( hir_defs . local_def_id ( id) , sp) )
1272
1289
. collect ( ) ,
1273
1290
glob_map : resolutions. glob_map . into_iter ( ) . map ( |( id, names) | {
1274
- ( hir . local_def_id ( id) , names)
1291
+ ( hir_defs . local_def_id ( id) , names)
1275
1292
} ) . collect ( ) ,
1276
1293
extern_prelude : resolutions. extern_prelude ,
1277
- hir_map : hir,
1294
+ hir_forest,
1295
+ hir_defs,
1296
+ hir_map : AtomicCell :: new ( None ) ,
1278
1297
def_path_hash_to_def_id,
1279
1298
queries : query:: Queries :: new (
1280
1299
providers,
@@ -1369,7 +1388,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1369
1388
/// be a non-local `DefPath`.
1370
1389
pub fn def_path ( self , id : DefId ) -> hir_map:: DefPath {
1371
1390
if id. is_local ( ) {
1372
- self . hir ( ) . def_path ( id)
1391
+ // FIXME: This is used in some panic path? Don't use hir()
1392
+ self . hir_defs . def_path ( id. index )
1373
1393
} else {
1374
1394
self . cstore . def_path ( id)
1375
1395
}
@@ -1378,7 +1398,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1378
1398
#[ inline]
1379
1399
pub fn def_path_hash ( self , def_id : DefId ) -> hir_map:: DefPathHash {
1380
1400
if def_id. is_local ( ) {
1381
- self . hir ( ) . definitions ( ) . def_path_hash ( def_id. index )
1401
+ // FIXME: This is used when executing the hir query, can't use hir() here
1402
+ self . hir_defs . def_path_hash ( def_id. index )
1382
1403
} else {
1383
1404
self . cstore . def_path_hash ( def_id)
1384
1405
}
@@ -1417,11 +1438,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
1417
1438
1418
1439
#[ inline( always) ]
1419
1440
pub fn create_stable_hashing_context ( self ) -> StableHashingContext < ' a > {
1420
- let krate = self . gcx . hir_map . forest . untracked_krate ( ) ;
1441
+ // FIXME: This is used when executing the hir query, can't use hir() here.
1442
+ // Also used when dealing with query cycles
1443
+ let krate = self . hir_forest . untracked_krate ( ) ;
1421
1444
1422
1445
StableHashingContext :: new ( self . sess ,
1423
1446
krate,
1424
- self . hir ( ) . definitions ( ) ,
1447
+ & self . hir_defs ,
1425
1448
self . cstore )
1426
1449
}
1427
1450
0 commit comments