9
9
// except according to those terms.
10
10
11
11
use hir;
12
- use hir:: def_id:: DefId ;
12
+ use hir:: def_id:: { DefId , DefIndex } ;
13
13
use hir:: map:: DefPathHash ;
14
14
use ich:: { self , CachingCodemapView } ;
15
15
use session:: config:: DebugInfoLevel :: NoDebugInfo ;
16
16
use ty:: { self , TyCtxt , fast_reject} ;
17
+ use session:: Session ;
17
18
18
19
use std:: cmp:: Ord ;
19
20
use std:: hash as std_hash;
@@ -42,6 +43,7 @@ thread_local!(static IGNORED_ATTR_NAMES: RefCell<FxHashSet<Symbol>> =
42
43
/// things (e.g. each DefId/DefPath is only hashed once).
43
44
pub struct StableHashingContext < ' a , ' gcx : ' a +' tcx , ' tcx : ' a > {
44
45
tcx : TyCtxt < ' a , ' gcx , ' tcx > ,
46
+ body_resolver : BodyResolver < ' gcx > ,
45
47
hash_spans : bool ,
46
48
hash_bodies : bool ,
47
49
overflow_checks_enabled : bool ,
@@ -59,6 +61,20 @@ pub enum NodeIdHashingMode {
59
61
HashDefPath ,
60
62
}
61
63
64
+ /// The BodyResolver allows to map a BodyId to the corresponding hir::Body.
65
+ /// We could also just store a plain reference to the hir::Crate but we want
66
+ /// to avoid that the crate is used to get untracked access to all of the HIR.
67
+ #[ derive( Clone , Copy ) ]
68
+ struct BodyResolver < ' hir > ( & ' hir hir:: Crate ) ;
69
+
70
+ impl < ' hir > BodyResolver < ' hir > {
71
+ // Return a reference to the hir::Body with the given BodyId.
72
+ // DOES NOT DO ANY TRACKING, use carefully.
73
+ fn body ( self , id : hir:: BodyId ) -> & ' hir hir:: Body {
74
+ self . 0 . body ( id)
75
+ }
76
+ }
77
+
62
78
impl < ' a , ' gcx , ' tcx > StableHashingContext < ' a , ' gcx , ' tcx > {
63
79
64
80
pub fn new ( tcx : TyCtxt < ' a , ' gcx , ' tcx > ) -> Self {
@@ -74,8 +90,11 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
74
90
}
75
91
} ) ;
76
92
93
+ let body_resolver = BodyResolver ( tcx. dep_graph . with_ignore ( || tcx. hir . krate ( ) ) ) ;
94
+
77
95
StableHashingContext {
78
96
tcx,
97
+ body_resolver,
79
98
caching_codemap : None ,
80
99
raw_codemap : tcx. sess . codemap ( ) ,
81
100
hash_spans : hash_spans_initial,
@@ -85,6 +104,11 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
85
104
}
86
105
}
87
106
107
+ #[ inline]
108
+ pub fn sess ( & self ) -> & ' gcx Session {
109
+ self . tcx . sess
110
+ }
111
+
88
112
pub fn force_span_hashing ( mut self ) -> Self {
89
113
self . hash_spans = true ;
90
114
self
@@ -121,13 +145,13 @@ impl<'a, 'gcx, 'tcx> StableHashingContext<'a, 'gcx, 'tcx> {
121
145
}
122
146
123
147
#[ inline]
124
- pub fn tcx ( & self ) -> TyCtxt < ' a , ' gcx , ' tcx > {
125
- self . tcx
148
+ pub fn def_path_hash ( & self , def_id : DefId ) -> DefPathHash {
149
+ self . tcx . def_path_hash ( def_id )
126
150
}
127
151
128
152
#[ inline]
129
- pub fn def_path_hash ( & mut self , def_id : DefId ) -> DefPathHash {
130
- self . tcx . def_path_hash ( def_id )
153
+ pub fn local_def_path_hash ( & self , def_index : DefIndex ) -> DefPathHash {
154
+ self . tcx . hir . definitions ( ) . def_path_hash ( def_index )
131
155
}
132
156
133
157
#[ inline]
@@ -221,6 +245,16 @@ impl<'a, 'gcx, 'lcx> StableHashingContextProvider for ty::TyCtxt<'a, 'gcx, 'lcx>
221
245
}
222
246
}
223
247
248
+ impl < ' a , ' gcx , ' tcx > HashStable < StableHashingContext < ' a , ' gcx , ' tcx > > for hir:: BodyId {
249
+ fn hash_stable < W : StableHasherResult > ( & self ,
250
+ hcx : & mut StableHashingContext < ' a , ' gcx , ' tcx > ,
251
+ hasher : & mut StableHasher < W > ) {
252
+ if hcx. hash_bodies ( ) {
253
+ hcx. body_resolver . body ( * self ) . hash_stable ( hcx, hasher) ;
254
+ }
255
+ }
256
+ }
257
+
224
258
impl < ' a , ' gcx , ' tcx > HashStable < StableHashingContext < ' a , ' gcx , ' tcx > > for hir:: HirId {
225
259
#[ inline]
226
260
fn hash_stable < W : StableHasherResult > ( & self ,
@@ -250,7 +284,7 @@ impl<'a, 'gcx, 'tcx> ToStableHashKey<StableHashingContext<'a, 'gcx, 'tcx>> for h
250
284
fn to_stable_hash_key ( & self ,
251
285
hcx : & StableHashingContext < ' a , ' gcx , ' tcx > )
252
286
-> ( DefPathHash , hir:: ItemLocalId ) {
253
- let def_path_hash = hcx. tcx ( ) . hir . definitions ( ) . def_path_hash ( self . owner ) ;
287
+ let def_path_hash = hcx. local_def_path_hash ( self . owner ) ;
254
288
( def_path_hash, self . local_id )
255
289
}
256
290
}
@@ -378,10 +412,9 @@ pub fn hash_stable_trait_impls<'a, 'tcx, 'gcx, W, R>(
378
412
}
379
413
380
414
{
381
- let tcx = hcx. tcx ( ) ;
382
415
let mut keys: AccumulateVec < [ _ ; 8 ] > =
383
416
non_blanket_impls. keys ( )
384
- . map ( |k| ( k, k. map_def ( |d| tcx . def_path_hash ( d) ) ) )
417
+ . map ( |k| ( k, k. map_def ( |d| hcx . def_path_hash ( d) ) ) )
385
418
. collect ( ) ;
386
419
keys. sort_unstable_by ( |& ( _, ref k1) , & ( _, ref k2) | k1. cmp ( k2) ) ;
387
420
keys. len ( ) . hash_stable ( hcx, hasher) ;
0 commit comments