@@ -8,6 +8,7 @@ use rustc_data_structures::fingerprint::{Fingerprint, FingerprintDecoder, Finger
8
8
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexSet } ;
9
9
use rustc_data_structures:: sync:: { HashMapExt , Lock , Lrc , OnceCell } ;
10
10
use rustc_data_structures:: thin_vec:: ThinVec ;
11
+ use rustc_data_structures:: unhash:: UnhashMap ;
11
12
use rustc_errors:: Diagnostic ;
12
13
use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , LocalDefId , LOCAL_CRATE } ;
13
14
use rustc_hir:: definitions:: DefPathHash ;
@@ -108,6 +109,19 @@ pub struct OnDiskCache<'sess> {
108
109
// may no longer exist in the current compilation session, so
109
110
// we use `Option<DefId>` so that we can cache a lookup failure.
110
111
def_path_hash_to_def_id_cache : Lock < FxHashMap < DefPathHash , Option < DefId > > > ,
112
+
113
+ // A map from a `DefPathHash` to its corresponding `DefId`, for all
114
+ // known `DefId`s (both foreign and local). Building this map takes
115
+ // a significant amount of time, so it is only initialized when
116
+ // needed by certain `-Z` flags (currently `-Z dump-dep-graph`).
117
+ // When this `OnceCell` is not initialized, the other fields of
118
+ // this struct (e.g. `foreign_def_path_hahses`) are used to map
119
+ // `DefPathHashes` to `DefId`s
120
+ //
121
+ // This field should *not* be used directly - the `def_path_hash_to_def_id`
122
+ // function should be used to map a `DefPathHash` to its corresponding
123
+ // `DefId`
124
+ debug_def_path_hash_to_def_id : OnceCell < UnhashMap < DefPathHash , DefId > > ,
111
125
}
112
126
113
127
// This type is used only for serialization and deserialization.
@@ -215,6 +229,7 @@ impl<'sess> OnDiskCache<'sess> {
215
229
latest_foreign_def_path_hashes : Default :: default ( ) ,
216
230
local_def_path_hash_to_def_id : make_local_def_path_hash_map ( definitions) ,
217
231
def_path_hash_to_def_id_cache : Default :: default ( ) ,
232
+ debug_def_path_hash_to_def_id : OnceCell :: new ( ) ,
218
233
}
219
234
}
220
235
@@ -237,6 +252,7 @@ impl<'sess> OnDiskCache<'sess> {
237
252
latest_foreign_def_path_hashes : Default :: default ( ) ,
238
253
local_def_path_hash_to_def_id : Default :: default ( ) ,
239
254
def_path_hash_to_def_id_cache : Default :: default ( ) ,
255
+ debug_def_path_hash_to_def_id : OnceCell :: new ( ) ,
240
256
}
241
257
}
242
258
@@ -474,6 +490,20 @@ impl<'sess> OnDiskCache<'sess> {
474
490
. insert ( hash, RawDefId { krate : def_id. krate . as_u32 ( ) , index : def_id. index . as_u32 ( ) } ) ;
475
491
}
476
492
493
+ pub fn build_debug_def_path_hash_map ( & self , tcx : TyCtxt < ' tcx > ) {
494
+ let crates = tcx. cstore . crates_untracked ( ) ;
495
+
496
+ let capacity = tcx. definitions . def_path_table ( ) . num_def_ids ( )
497
+ + crates. iter ( ) . map ( |cnum| tcx. cstore . num_def_ids ( * cnum) ) . sum :: < usize > ( ) ;
498
+ let mut map = UnhashMap :: with_capacity_and_hasher ( capacity, Default :: default ( ) ) ;
499
+
500
+ map. extend ( tcx. definitions . def_path_table ( ) . all_def_path_hashes_and_def_ids ( LOCAL_CRATE ) ) ;
501
+ for cnum in & crates {
502
+ map. extend ( tcx. cstore . debug_all_def_path_hashes_and_def_ids ( * cnum) . into_iter ( ) ) ;
503
+ }
504
+ self . debug_def_path_hash_to_def_id . set ( map) . unwrap ( ) ;
505
+ }
506
+
477
507
/// If the given `dep_node`'s hash still exists in the current compilation,
478
508
/// and its current `DefId` is foreign, calls `store_foreign_def_id` with it.
479
509
///
@@ -625,6 +655,14 @@ impl<'sess> OnDiskCache<'sess> {
625
655
Entry :: Occupied ( e) => * e. get ( ) ,
626
656
Entry :: Vacant ( e) => {
627
657
debug ! ( "def_path_hash_to_def_id({:?})" , hash) ;
658
+
659
+ if let Some ( debug_map) = self . debug_def_path_hash_to_def_id . get ( ) {
660
+ if let Some ( def_id) = debug_map. get ( & hash) . copied ( ) {
661
+ e. insert ( Some ( def_id) ) ;
662
+ return Some ( def_id) ;
663
+ }
664
+ }
665
+
628
666
// Check if the `DefPathHash` corresponds to a definition in the current
629
667
// crate
630
668
if let Some ( def_id) = self . local_def_path_hash_to_def_id . get ( & hash) . cloned ( ) {
0 commit comments