1
- use crate :: arena:: Arena ;
2
- use crate :: hir:: map:: Map ;
3
- use crate :: hir:: { IndexedHir , OwnerNodes , ParentedNode } ;
4
- use rustc_data_structures:: fingerprint:: Fingerprint ;
5
1
use rustc_data_structures:: fx:: FxHashMap ;
6
- use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher } ;
7
2
use rustc_hir as hir;
8
3
use rustc_hir:: def_id:: LocalDefId ;
9
- use rustc_hir:: def_id:: CRATE_DEF_ID ;
10
4
use rustc_hir:: definitions;
11
5
use rustc_hir:: intravisit:: { self , NestedVisitorMap , Visitor } ;
12
6
use rustc_hir:: * ;
13
7
use rustc_index:: vec:: { Idx , IndexVec } ;
14
- use rustc_query_system:: ich:: StableHashingContext ;
15
8
use rustc_session:: Session ;
16
9
use rustc_span:: source_map:: SourceMap ;
17
10
use rustc_span:: { Span , DUMMY_SP } ;
18
11
19
12
use std:: iter:: repeat;
13
+ use tracing:: debug;
20
14
21
15
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
22
16
pub ( super ) struct NodeCollector < ' a , ' hir > {
23
- arena : & ' hir Arena < ' hir > ,
24
-
25
- /// The crate
26
- krate : & ' hir Crate < ' hir > ,
27
-
28
17
/// Source map
29
18
source_map : & ' a SourceMap ,
19
+ bodies : & ' a IndexVec < ItemLocalId , Option < & ' hir Body < ' hir > > > ,
30
20
31
- map : IndexVec < LocalDefId , Option < & ' hir mut OwnerNodes < ' hir > > > ,
32
- parenting : FxHashMap < LocalDefId , HirId > ,
21
+ /// Outputs
22
+ nodes : IndexVec < ItemLocalId , Option < ParentedNode < ' hir > > > ,
23
+ parenting : FxHashMap < LocalDefId , ItemLocalId > ,
33
24
34
25
/// The parent of this node
35
- parent_node : hir:: HirId ,
26
+ parent_node : hir:: ItemLocalId ,
36
27
37
- current_dep_node_owner : LocalDefId ,
28
+ owner : LocalDefId ,
38
29
39
30
definitions : & ' a definitions:: Definitions ,
40
-
41
- hcx : StableHashingContext < ' a > ,
42
31
}
43
32
44
33
fn insert_vec_map < K : Idx , V : Clone > ( map : & mut IndexVec < K , Option < V > > , k : K , v : V ) {
@@ -51,137 +40,82 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
51
40
map[ k] = Some ( v) ;
52
41
}
53
42
54
- fn hash_body (
55
- hcx : & mut StableHashingContext < ' _ > ,
56
- item_like : impl for < ' a > HashStable < StableHashingContext < ' a > > ,
57
- ) -> Fingerprint {
58
- let mut stable_hasher = StableHasher :: new ( ) ;
59
- hcx. while_hashing_hir_bodies ( true , |hcx| {
60
- item_like. hash_stable ( hcx, & mut stable_hasher) ;
61
- } ) ;
62
- stable_hasher. finish ( )
43
+ pub ( super ) fn index_hir < ' hir > (
44
+ sess : & Session ,
45
+ definitions : & definitions:: Definitions ,
46
+ item : hir:: OwnerNode < ' hir > ,
47
+ bodies : & IndexVec < ItemLocalId , Option < & ' hir Body < ' hir > > > ,
48
+ ) -> ( IndexVec < ItemLocalId , Option < ParentedNode < ' hir > > > , FxHashMap < LocalDefId , ItemLocalId > ) {
49
+ let mut nodes = IndexVec :: new ( ) ;
50
+ // This node's parent should never be accessed: the owner's parent is computed by the
51
+ // hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
52
+ // used.
53
+ nodes. push ( Some ( ParentedNode { parent : ItemLocalId :: INVALID , node : item. into ( ) } ) ) ;
54
+ let mut collector = NodeCollector {
55
+ source_map : sess. source_map ( ) ,
56
+ definitions,
57
+ owner : item. def_id ( ) ,
58
+ parent_node : ItemLocalId :: new ( 0 ) ,
59
+ nodes,
60
+ bodies,
61
+ parenting : FxHashMap :: default ( ) ,
62
+ } ;
63
+
64
+ match item {
65
+ OwnerNode :: Crate ( citem) => collector. visit_mod ( & citem, citem. inner , hir:: CRATE_HIR_ID ) ,
66
+ OwnerNode :: Item ( item) => collector. visit_item ( item) ,
67
+ OwnerNode :: TraitItem ( item) => collector. visit_trait_item ( item) ,
68
+ OwnerNode :: ImplItem ( item) => collector. visit_impl_item ( item) ,
69
+ OwnerNode :: ForeignItem ( item) => collector. visit_foreign_item ( item) ,
70
+ } ;
71
+
72
+ ( collector. nodes , collector. parenting )
63
73
}
64
74
65
75
impl < ' a , ' hir > NodeCollector < ' a , ' hir > {
66
- pub ( super ) fn root (
67
- sess : & ' a Session ,
68
- arena : & ' hir Arena < ' hir > ,
69
- krate : & ' hir Crate < ' hir > ,
70
- definitions : & ' a definitions:: Definitions ,
71
- hcx : StableHashingContext < ' a > ,
72
- ) -> NodeCollector < ' a , ' hir > {
73
- let mut collector = NodeCollector {
74
- arena,
75
- krate,
76
- source_map : sess. source_map ( ) ,
77
- parent_node : hir:: CRATE_HIR_ID ,
78
- current_dep_node_owner : CRATE_DEF_ID ,
79
- definitions,
80
- hcx,
81
- map : IndexVec :: from_fn_n ( |_| None , definitions. def_index_count ( ) ) ,
82
- parenting : FxHashMap :: default ( ) ,
83
- } ;
84
- collector. insert_owner ( CRATE_DEF_ID , OwnerNode :: Crate ( krate. module ( ) ) ) ;
85
-
86
- collector
87
- }
88
-
89
- pub ( super ) fn finalize_and_compute_crate_hash ( mut self ) -> IndexedHir < ' hir > {
90
- // Insert bodies into the map
91
- for ( id, body) in self . krate . bodies . iter ( ) {
92
- let bodies = & mut self . map [ id. hir_id . owner ] . as_mut ( ) . unwrap ( ) . bodies ;
93
- assert ! ( bodies. insert( id. hir_id. local_id, body) . is_none( ) ) ;
94
- }
95
- IndexedHir { map : self . map , parenting : self . parenting }
96
- }
97
-
98
- fn insert_owner ( & mut self , owner : LocalDefId , node : OwnerNode < ' hir > ) {
99
- let hash = hash_body ( & mut self . hcx , node) ;
100
-
101
- let mut nodes = IndexVec :: new ( ) ;
102
- nodes. push ( Some ( ParentedNode { parent : ItemLocalId :: new ( 0 ) , node : node. into ( ) } ) ) ;
103
-
104
- debug_assert ! ( self . map[ owner] . is_none( ) ) ;
105
- self . map [ owner] =
106
- Some ( self . arena . alloc ( OwnerNodes { hash, nodes, bodies : FxHashMap :: default ( ) } ) ) ;
107
- }
108
-
109
76
fn insert ( & mut self , span : Span , hir_id : HirId , node : Node < ' hir > ) {
110
- debug_assert_eq ! ( self . current_dep_node_owner , hir_id. owner) ;
77
+ debug_assert_eq ! ( self . owner , hir_id. owner) ;
111
78
debug_assert_ne ! ( hir_id. local_id. as_u32( ) , 0 ) ;
112
79
113
80
// Make sure that the DepNode of some node coincides with the HirId
114
81
// owner of that node.
115
82
if cfg ! ( debug_assertions) {
116
- if hir_id. owner != self . current_dep_node_owner {
117
- let node_str = match self . definitions . opt_hir_id_to_local_def_id ( hir_id) {
118
- Some ( def_id) => self . definitions . def_path ( def_id) . to_string_no_crate_verbose ( ) ,
119
- None => format ! ( "{:?}" , node) ,
120
- } ;
121
-
122
- span_bug ! (
123
- span,
124
- "inconsistent DepNode at `{:?}` for `{}`: \
83
+ if hir_id. owner != self . owner {
84
+ panic ! (
85
+ "inconsistent DepNode at `{:?}` for `{:?}`: \
125
86
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
126
87
self . source_map. span_to_diagnostic_string( span) ,
127
- node_str,
128
- self . definitions
129
- . def_path( self . current_dep_node_owner)
130
- . to_string_no_crate_verbose( ) ,
131
- self . current_dep_node_owner,
88
+ node,
89
+ self . definitions. def_path( self . owner) . to_string_no_crate_verbose( ) ,
90
+ self . owner,
132
91
self . definitions. def_path( hir_id. owner) . to_string_no_crate_verbose( ) ,
133
92
hir_id. owner,
134
93
)
135
94
}
136
95
}
137
96
138
- let nodes = self . map [ hir_id. owner ] . as_mut ( ) . unwrap ( ) ;
139
-
140
- debug_assert_eq ! ( self . parent_node. owner, self . current_dep_node_owner) ;
141
97
insert_vec_map (
142
- & mut nodes . nodes ,
98
+ & mut self . nodes ,
143
99
hir_id. local_id ,
144
- ParentedNode { parent : self . parent_node . local_id , node : node } ,
100
+ ParentedNode { parent : self . parent_node , node : node } ,
145
101
) ;
146
102
}
147
103
148
104
fn with_parent < F : FnOnce ( & mut Self ) > ( & mut self , parent_node_id : HirId , f : F ) {
105
+ debug_assert_eq ! ( parent_node_id. owner, self . owner) ;
149
106
let parent_node = self . parent_node ;
150
- self . parent_node = parent_node_id;
107
+ self . parent_node = parent_node_id. local_id ;
151
108
f ( self ) ;
152
109
self . parent_node = parent_node;
153
110
}
154
111
155
- fn with_dep_node_owner ( & mut self , dep_node_owner : LocalDefId , f : impl FnOnce ( & mut Self ) ) {
156
- let prev_owner = self . current_dep_node_owner ;
157
- let prev_parent = self . parent_node ;
158
-
159
- self . current_dep_node_owner = dep_node_owner;
160
- self . parent_node = HirId :: make_owner ( dep_node_owner) ;
161
- f ( self ) ;
162
- self . current_dep_node_owner = prev_owner;
163
- self . parent_node = prev_parent;
164
- }
165
-
166
112
fn insert_nested ( & mut self , item : LocalDefId ) {
167
- #[ cfg( debug_assertions) ]
168
- {
169
- let dk_parent = self . definitions . def_key ( item) . parent . unwrap ( ) ;
170
- let dk_parent = LocalDefId { local_def_index : dk_parent } ;
171
- let dk_parent = self . definitions . local_def_id_to_hir_id ( dk_parent) ;
172
- debug_assert_eq ! (
173
- dk_parent. owner, self . parent_node. owner,
174
- "Different parents for {:?}" ,
175
- item
176
- )
177
- }
178
-
179
- assert_eq ! ( self . parenting. insert( item, self . parent_node) , None ) ;
113
+ self . parenting . insert ( item, self . parent_node ) ;
180
114
}
181
115
}
182
116
183
117
impl < ' a , ' hir > Visitor < ' hir > for NodeCollector < ' a , ' hir > {
184
- type Map = Map < ' hir > ;
118
+ type Map = ! ;
185
119
186
120
/// Because we want to track parent items and so forth, enable
187
121
/// deep walking so that we walk nested items in the context of
@@ -194,26 +128,24 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
194
128
fn visit_nested_item ( & mut self , item : ItemId ) {
195
129
debug ! ( "visit_nested_item: {:?}" , item) ;
196
130
self . insert_nested ( item. def_id ) ;
197
- self . visit_item ( self . krate . item ( item) ) ;
198
131
}
199
132
200
133
fn visit_nested_trait_item ( & mut self , item_id : TraitItemId ) {
201
134
self . insert_nested ( item_id. def_id ) ;
202
- self . visit_trait_item ( self . krate . trait_item ( item_id) ) ;
203
135
}
204
136
205
137
fn visit_nested_impl_item ( & mut self , item_id : ImplItemId ) {
206
138
self . insert_nested ( item_id. def_id ) ;
207
- self . visit_impl_item ( self . krate . impl_item ( item_id) ) ;
208
139
}
209
140
210
141
fn visit_nested_foreign_item ( & mut self , foreign_id : ForeignItemId ) {
211
142
self . insert_nested ( foreign_id. def_id ) ;
212
- self . visit_foreign_item ( self . krate . foreign_item ( foreign_id) ) ;
213
143
}
214
144
215
145
fn visit_nested_body ( & mut self , id : BodyId ) {
216
- self . visit_body ( self . krate . body ( id) ) ;
146
+ debug_assert_eq ! ( id. hir_id. owner, self . owner) ;
147
+ let body = self . bodies [ id. hir_id . local_id ] . unwrap ( ) ;
148
+ self . visit_body ( body) ;
217
149
}
218
150
219
151
fn visit_param ( & mut self , param : & ' hir Param < ' hir > ) {
@@ -226,8 +158,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
226
158
227
159
fn visit_item ( & mut self , i : & ' hir Item < ' hir > ) {
228
160
debug ! ( "visit_item: {:?}" , i) ;
229
- self . insert_owner ( i. def_id , OwnerNode :: Item ( i ) ) ;
230
- self . with_dep_node_owner ( i. def_id , |this| {
161
+ debug_assert_eq ! ( i. def_id, self . owner ) ;
162
+ self . with_parent ( i. hir_id ( ) , |this| {
231
163
if let ItemKind :: Struct ( ref struct_def, _) = i. kind {
232
164
// If this is a tuple or unit-like struct, register the constructor.
233
165
if let Some ( ctor_hir_id) = struct_def. ctor_hir_id ( ) {
@@ -239,8 +171,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
239
171
}
240
172
241
173
fn visit_foreign_item ( & mut self , fi : & ' hir ForeignItem < ' hir > ) {
242
- self . insert_owner ( fi. def_id , OwnerNode :: ForeignItem ( fi ) ) ;
243
- self . with_dep_node_owner ( fi. def_id , |this| {
174
+ debug_assert_eq ! ( fi. def_id, self . owner ) ;
175
+ self . with_parent ( fi. hir_id ( ) , |this| {
244
176
intravisit:: walk_foreign_item ( this, fi) ;
245
177
} ) ;
246
178
}
@@ -257,15 +189,15 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
257
189
}
258
190
259
191
fn visit_trait_item ( & mut self , ti : & ' hir TraitItem < ' hir > ) {
260
- self . insert_owner ( ti. def_id , OwnerNode :: TraitItem ( ti ) ) ;
261
- self . with_dep_node_owner ( ti. def_id , |this| {
192
+ debug_assert_eq ! ( ti. def_id, self . owner ) ;
193
+ self . with_parent ( ti. hir_id ( ) , |this| {
262
194
intravisit:: walk_trait_item ( this, ti) ;
263
195
} ) ;
264
196
}
265
197
266
198
fn visit_impl_item ( & mut self , ii : & ' hir ImplItem < ' hir > ) {
267
- self . insert_owner ( ii. def_id , OwnerNode :: ImplItem ( ii ) ) ;
268
- self . with_dep_node_owner ( ii. def_id , |this| {
199
+ debug_assert_eq ! ( ii. def_id, self . owner ) ;
200
+ self . with_parent ( ii. hir_id ( ) , |this| {
269
201
intravisit:: walk_impl_item ( this, ii) ;
270
202
} ) ;
271
203
}
@@ -353,7 +285,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
353
285
s : Span ,
354
286
id : HirId ,
355
287
) {
356
- assert_eq ! ( self . parent_node, id) ;
288
+ assert_eq ! ( self . owner, id. owner) ;
289
+ assert_eq ! ( self . parent_node, id. local_id) ;
357
290
intravisit:: walk_fn ( self , fk, fd, b, s, id) ;
358
291
}
359
292
0 commit comments