@@ -16,6 +16,9 @@ use std::iter::repeat;
16
16
use syntax:: ast:: { NodeId , CRATE_NODE_ID } ;
17
17
use syntax_pos:: Span ;
18
18
19
+ use ich:: StableHashingContext ;
20
+ use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher , StableHasherResult } ;
21
+
19
22
/// A Visitor that walks over the HIR and collects Nodes into a HIR map
20
23
pub ( super ) struct NodeCollector < ' a , ' hir > {
21
24
/// The crate
@@ -26,36 +29,99 @@ pub(super) struct NodeCollector<'a, 'hir> {
26
29
parent_node : NodeId ,
27
30
28
31
current_dep_node_owner : DefIndex ,
29
- current_dep_node_index : DepNodeIndex ,
32
+ current_signature_dep_index : DepNodeIndex ,
33
+ current_full_dep_index : DepNodeIndex ,
34
+ currently_in_body : bool ,
30
35
31
36
dep_graph : & ' a DepGraph ,
32
37
definitions : & ' a definitions:: Definitions ,
38
+
39
+ hcx : StableHashingContext < ' a > ,
40
+
41
+ hir_body_nodes : Vec < DefPathHash > ,
33
42
}
34
43
35
44
impl < ' a , ' hir > NodeCollector < ' a , ' hir > {
36
45
pub ( super ) fn root ( krate : & ' hir Crate ,
37
- dep_graph : & ' a DepGraph ,
38
- definitions : & ' a definitions:: Definitions )
46
+ dep_graph : & ' a DepGraph ,
47
+ definitions : & ' a definitions:: Definitions ,
48
+ hcx : StableHashingContext < ' a > )
39
49
-> NodeCollector < ' a , ' hir > {
40
50
let root_mod_def_path_hash = definitions. def_path_hash ( CRATE_DEF_INDEX ) ;
41
- let root_mod_dep_node = root_mod_def_path_hash. to_dep_node ( DepKind :: Hir ) ;
42
- let root_mod_dep_node_index = dep_graph. alloc_input_node ( root_mod_dep_node) ;
51
+
52
+ // Allocate DepNodes for the root module
53
+ let ( root_mod_sig_dep_index, root_mod_full_dep_index) ;
54
+ {
55
+ let Crate {
56
+ ref module,
57
+ // Crate attributes are not copied over to the root `Mod`, so hash
58
+ // them explicitly here.
59
+ ref attrs,
60
+ span,
61
+
62
+ // These fields are handled separately:
63
+ exported_macros : _,
64
+ items : _,
65
+ trait_items : _,
66
+ impl_items : _,
67
+ bodies : _,
68
+ trait_impls : _,
69
+ trait_default_impl : _,
70
+ body_ids : _,
71
+ } = * krate;
72
+
73
+ root_mod_sig_dep_index = dep_graph. with_task (
74
+ root_mod_def_path_hash. to_dep_node ( DepKind :: Hir ) ,
75
+ & hcx,
76
+ HirItemLike { item_like : ( module, attrs, span) , hash_bodies : false } ,
77
+ identity_fn
78
+ ) . 1 ;
79
+ root_mod_full_dep_index = dep_graph. with_task (
80
+ root_mod_def_path_hash. to_dep_node ( DepKind :: HirBody ) ,
81
+ & hcx,
82
+ HirItemLike { item_like : ( module, attrs, span) , hash_bodies : true } ,
83
+ identity_fn
84
+ ) . 1 ;
85
+ }
86
+
87
+ let hir_body_nodes = vec ! [ root_mod_def_path_hash] ;
43
88
44
89
let mut collector = NodeCollector {
45
90
krate,
46
91
map : vec ! [ ] ,
47
92
parent_node : CRATE_NODE_ID ,
48
- current_dep_node_index : root_mod_dep_node_index,
93
+ current_signature_dep_index : root_mod_sig_dep_index,
94
+ current_full_dep_index : root_mod_full_dep_index,
49
95
current_dep_node_owner : CRATE_DEF_INDEX ,
96
+ currently_in_body : false ,
50
97
dep_graph,
51
98
definitions,
99
+ hcx,
100
+ hir_body_nodes,
52
101
} ;
53
- collector. insert_entry ( CRATE_NODE_ID , RootCrate ( root_mod_dep_node_index ) ) ;
102
+ collector. insert_entry ( CRATE_NODE_ID , RootCrate ( root_mod_sig_dep_index ) ) ;
54
103
55
104
collector
56
105
}
57
106
58
- pub ( super ) fn into_map ( self ) -> Vec < MapEntry < ' hir > > {
107
+ pub ( super ) fn finalize_and_compute_crate_hash ( self ,
108
+ crate_disambiguator : & str )
109
+ -> Vec < MapEntry < ' hir > > {
110
+ let mut node_hashes: Vec < _ > = self
111
+ . hir_body_nodes
112
+ . iter ( )
113
+ . map ( |& def_path_hash| {
114
+ let dep_node = def_path_hash. to_dep_node ( DepKind :: HirBody ) ;
115
+ ( def_path_hash, self . dep_graph . fingerprint_of ( & dep_node) )
116
+ } )
117
+ . collect ( ) ;
118
+
119
+ node_hashes. sort_unstable_by ( |& ( ref d1, _) , & ( ref d2, _) | d1. cmp ( d2) ) ;
120
+
121
+ self . dep_graph . with_task ( DepNode :: new_no_params ( DepKind :: Krate ) ,
122
+ & self . hcx ,
123
+ ( node_hashes, crate_disambiguator) ,
124
+ identity_fn) ;
59
125
self . map
60
126
}
61
127
@@ -70,7 +136,11 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
70
136
71
137
fn insert ( & mut self , id : NodeId , node : Node < ' hir > ) {
72
138
let parent = self . parent_node ;
73
- let dep_node_index = self . current_dep_node_index ;
139
+ let dep_node_index = if self . currently_in_body {
140
+ self . current_full_dep_index
141
+ } else {
142
+ self . current_signature_dep_index
143
+ } ;
74
144
75
145
let entry = match node {
76
146
NodeItem ( n) => EntryItem ( parent, dep_node_index, n) ,
@@ -91,6 +161,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
91
161
NodeTyParam ( n) => EntryTyParam ( parent, dep_node_index, n) ,
92
162
NodeVisibility ( n) => EntryVisibility ( parent, dep_node_index, n) ,
93
163
NodeLocal ( n) => EntryLocal ( parent, dep_node_index, n) ,
164
+ NodeMacroDef ( n) => EntryMacroDef ( dep_node_index, n) ,
94
165
} ;
95
166
96
167
// Make sure that the DepNode of some node coincides with the HirId
@@ -127,22 +198,41 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
127
198
self . parent_node = parent_node;
128
199
}
129
200
130
- fn with_dep_node_owner < F : FnOnce ( & mut Self ) > ( & mut self ,
201
+ fn with_dep_node_owner < T : HashStable < StableHashingContext < ' a > > ,
202
+ F : FnOnce ( & mut Self ) > ( & mut self ,
131
203
dep_node_owner : DefIndex ,
204
+ item_like : & T ,
132
205
f : F ) {
133
206
let prev_owner = self . current_dep_node_owner ;
134
- let prev_index = self . current_dep_node_index ;
135
-
136
- // When we enter a new owner (item, impl item, or trait item), we always
137
- // start out again with DepKind::Hir.
138
- let new_dep_node = self . definitions
139
- . def_path_hash ( dep_node_owner)
140
- . to_dep_node ( DepKind :: Hir ) ;
141
- self . current_dep_node_index = self . dep_graph . alloc_input_node ( new_dep_node) ;
207
+ let prev_signature_dep_index = self . current_signature_dep_index ;
208
+ let prev_full_dep_index = self . current_signature_dep_index ;
209
+ let prev_in_body = self . currently_in_body ;
210
+
211
+ let def_path_hash = self . definitions . def_path_hash ( dep_node_owner) ;
212
+
213
+ self . current_signature_dep_index = self . dep_graph . with_task (
214
+ def_path_hash. to_dep_node ( DepKind :: Hir ) ,
215
+ & self . hcx ,
216
+ HirItemLike { item_like, hash_bodies : false } ,
217
+ identity_fn
218
+ ) . 1 ;
219
+
220
+ self . current_full_dep_index = self . dep_graph . with_task (
221
+ def_path_hash. to_dep_node ( DepKind :: HirBody ) ,
222
+ & self . hcx ,
223
+ HirItemLike { item_like, hash_bodies : true } ,
224
+ identity_fn
225
+ ) . 1 ;
226
+
227
+ self . hir_body_nodes . push ( def_path_hash) ;
228
+
142
229
self . current_dep_node_owner = dep_node_owner;
230
+ self . currently_in_body = false ;
143
231
f ( self ) ;
144
- self . current_dep_node_index = prev_index ;
232
+ self . currently_in_body = prev_in_body ;
145
233
self . current_dep_node_owner = prev_owner;
234
+ self . current_full_dep_index = prev_full_dep_index;
235
+ self . current_signature_dep_index = prev_signature_dep_index;
146
236
}
147
237
}
148
238
@@ -169,24 +259,17 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
169
259
}
170
260
171
261
fn visit_nested_body ( & mut self , id : BodyId ) {
172
- // When we enter a body, we switch to DepKind::HirBody.
173
- // Note that current_dep_node_index might already be DepKind::HirBody,
174
- // e.g. when entering the body of a closure that is already part of a
175
- // surrounding body. That's expected and not a problem.
176
- let prev_index = self . current_dep_node_index ;
177
- let new_dep_node = self . definitions
178
- . def_path_hash ( self . current_dep_node_owner )
179
- . to_dep_node ( DepKind :: HirBody ) ;
180
- self . current_dep_node_index = self . dep_graph . alloc_input_node ( new_dep_node) ;
262
+ let prev_in_body = self . currently_in_body ;
263
+ self . currently_in_body = true ;
181
264
self . visit_body ( self . krate . body ( id) ) ;
182
- self . current_dep_node_index = prev_index ;
265
+ self . currently_in_body = prev_in_body ;
183
266
}
184
267
185
268
fn visit_item ( & mut self , i : & ' hir Item ) {
186
269
debug ! ( "visit_item: {:?}" , i) ;
187
270
debug_assert_eq ! ( i. hir_id. owner,
188
271
self . definitions. opt_def_index( i. id) . unwrap( ) ) ;
189
- self . with_dep_node_owner ( i. hir_id . owner , |this| {
272
+ self . with_dep_node_owner ( i. hir_id . owner , i , |this| {
190
273
this. insert ( i. id , NodeItem ( i) ) ;
191
274
this. with_parent ( i. id , |this| {
192
275
match i. node {
@@ -222,7 +305,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
222
305
fn visit_trait_item ( & mut self , ti : & ' hir TraitItem ) {
223
306
debug_assert_eq ! ( ti. hir_id. owner,
224
307
self . definitions. opt_def_index( ti. id) . unwrap( ) ) ;
225
- self . with_dep_node_owner ( ti. hir_id . owner , |this| {
308
+ self . with_dep_node_owner ( ti. hir_id . owner , ti , |this| {
226
309
this. insert ( ti. id , NodeTraitItem ( ti) ) ;
227
310
228
311
this. with_parent ( ti. id , |this| {
@@ -234,7 +317,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
234
317
fn visit_impl_item ( & mut self , ii : & ' hir ImplItem ) {
235
318
debug_assert_eq ! ( ii. hir_id. owner,
236
319
self . definitions. opt_def_index( ii. id) . unwrap( ) ) ;
237
- self . with_dep_node_owner ( ii. hir_id . owner , |this| {
320
+ self . with_dep_node_owner ( ii. hir_id . owner , ii , |this| {
238
321
this. insert ( ii. id , NodeImplItem ( ii) ) ;
239
322
240
323
this. with_parent ( ii. id , |this| {
@@ -328,7 +411,11 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
328
411
}
329
412
330
413
fn visit_macro_def ( & mut self , macro_def : & ' hir MacroDef ) {
331
- self . insert_entry ( macro_def. id , NotPresent ) ;
414
+ let def_index = self . definitions . opt_def_index ( macro_def. id ) . unwrap ( ) ;
415
+
416
+ self . with_dep_node_owner ( def_index, macro_def, |this| {
417
+ this. insert ( macro_def. id , NodeMacroDef ( macro_def) ) ;
418
+ } ) ;
332
419
}
333
420
334
421
fn visit_variant ( & mut self , v : & ' hir Variant , g : & ' hir Generics , item_id : NodeId ) {
@@ -375,3 +462,25 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
375
462
self . visit_nested_impl_item ( id) ;
376
463
}
377
464
}
465
+
466
+
467
+ fn identity_fn < T > ( _: & StableHashingContext , item_like : T ) -> T {
468
+ item_like
469
+ }
470
+
471
+ struct HirItemLike < T > {
472
+ item_like : T ,
473
+ hash_bodies : bool ,
474
+ }
475
+
476
+ impl < ' hir , T > HashStable < StableHashingContext < ' hir > > for HirItemLike < T >
477
+ where T : HashStable < StableHashingContext < ' hir > >
478
+ {
479
+ fn hash_stable < W : StableHasherResult > ( & self ,
480
+ hcx : & mut StableHashingContext < ' hir > ,
481
+ hasher : & mut StableHasher < W > ) {
482
+ hcx. while_hashing_hir_bodies ( self . hash_bodies , |hcx| {
483
+ self . item_like . hash_stable ( hcx, hasher) ;
484
+ } ) ;
485
+ }
486
+ }
0 commit comments