@@ -37,10 +37,10 @@ fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
37
37
}
38
38
}
39
39
40
- struct MarkSymbolVisitor < ' a , ' tcx > {
40
+ struct MarkSymbolVisitor < ' tcx > {
41
41
worklist : Vec < hir:: HirId > ,
42
42
tcx : TyCtxt < ' tcx > ,
43
- tables : & ' a ty:: TypeckTables < ' tcx > ,
43
+ maybe_typeck_tables : Option < & ' tcx ty:: TypeckTables < ' tcx > > ,
44
44
live_symbols : FxHashSet < hir:: HirId > ,
45
45
repr_has_repr_c : bool ,
46
46
in_pat : bool ,
@@ -50,7 +50,15 @@ struct MarkSymbolVisitor<'a, 'tcx> {
50
50
struct_constructors : FxHashMap < hir:: HirId , hir:: HirId > ,
51
51
}
52
52
53
- impl < ' a , ' tcx > MarkSymbolVisitor < ' a , ' tcx > {
53
+ impl < ' tcx > MarkSymbolVisitor < ' tcx > {
54
+ /// Gets the type-checking side-tables for the current body.
55
+ /// As this will ICE if called outside bodies, only call when working with
56
+ /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
57
+ #[ track_caller]
58
+ fn tables ( & self ) -> & ' tcx ty:: TypeckTables < ' tcx > {
59
+ self . maybe_typeck_tables . expect ( "`MarkSymbolVisitor::tables` called outside of body" )
60
+ }
61
+
54
62
fn check_def_id ( & mut self , def_id : DefId ) {
55
63
if let Some ( def_id) = def_id. as_local ( ) {
56
64
let hir_id = self . tcx . hir ( ) . as_local_hir_id ( def_id) ;
@@ -107,17 +115,17 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
107
115
}
108
116
109
117
fn lookup_and_handle_method ( & mut self , id : hir:: HirId ) {
110
- if let Some ( def_id) = self . tables . type_dependent_def_id ( id) {
118
+ if let Some ( def_id) = self . tables ( ) . type_dependent_def_id ( id) {
111
119
self . check_def_id ( def_id) ;
112
120
} else {
113
121
bug ! ( "no type-dependent def for method" ) ;
114
122
}
115
123
}
116
124
117
125
fn handle_field_access ( & mut self , lhs : & hir:: Expr < ' _ > , hir_id : hir:: HirId ) {
118
- match self . tables . expr_ty_adjusted ( lhs) . kind {
126
+ match self . tables ( ) . expr_ty_adjusted ( lhs) . kind {
119
127
ty:: Adt ( def, _) => {
120
- let index = self . tcx . field_index ( hir_id, self . tables ) ;
128
+ let index = self . tcx . field_index ( hir_id, self . tables ( ) ) ;
121
129
self . insert_def_id ( def. non_enum_variant ( ) . fields [ index] . did ) ;
122
130
}
123
131
ty:: Tuple ( ..) => { }
@@ -131,15 +139,15 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
131
139
res : Res ,
132
140
pats : & [ hir:: FieldPat < ' _ > ] ,
133
141
) {
134
- let variant = match self . tables . node_type ( lhs. hir_id ) . kind {
142
+ let variant = match self . tables ( ) . node_type ( lhs. hir_id ) . kind {
135
143
ty:: Adt ( adt, _) => adt. variant_of_res ( res) ,
136
144
_ => span_bug ! ( lhs. span, "non-ADT in struct pattern" ) ,
137
145
} ;
138
146
for pat in pats {
139
147
if let PatKind :: Wild = pat. pat . kind {
140
148
continue ;
141
149
}
142
- let index = self . tcx . field_index ( pat. hir_id , self . tables ) ;
150
+ let index = self . tcx . field_index ( pat. hir_id , self . tables ( ) ) ;
143
151
self . insert_def_id ( variant. fields [ index] . did ) ;
144
152
}
145
153
}
@@ -204,26 +212,25 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
204
212
fn mark_as_used_if_union ( & mut self , adt : & ty:: AdtDef , fields : & [ hir:: Field < ' _ > ] ) {
205
213
if adt. is_union ( ) && adt. non_enum_variant ( ) . fields . len ( ) > 1 && adt. did . is_local ( ) {
206
214
for field in fields {
207
- let index = self . tcx . field_index ( field. hir_id , self . tables ) ;
215
+ let index = self . tcx . field_index ( field. hir_id , self . tables ( ) ) ;
208
216
self . insert_def_id ( adt. non_enum_variant ( ) . fields [ index] . did ) ;
209
217
}
210
218
}
211
219
}
212
220
}
213
221
214
- impl < ' a , ' tcx > Visitor < ' tcx > for MarkSymbolVisitor < ' a , ' tcx > {
222
+ impl < ' tcx > Visitor < ' tcx > for MarkSymbolVisitor < ' tcx > {
215
223
type Map = intravisit:: ErasedMap < ' tcx > ;
216
224
217
225
fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
218
226
NestedVisitorMap :: None
219
227
}
220
228
221
229
fn visit_nested_body ( & mut self , body : hir:: BodyId ) {
222
- let old_tables = self . tables ;
223
- self . tables = self . tcx . body_tables ( body) ;
230
+ let old_maybe_typeck_tables = self . maybe_typeck_tables . replace ( self . tcx . body_tables ( body) ) ;
224
231
let body = self . tcx . hir ( ) . body ( body) ;
225
232
self . visit_body ( body) ;
226
- self . tables = old_tables ;
233
+ self . maybe_typeck_tables = old_maybe_typeck_tables ;
227
234
}
228
235
229
236
fn visit_variant_data (
@@ -248,7 +255,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
248
255
fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr < ' tcx > ) {
249
256
match expr. kind {
250
257
hir:: ExprKind :: Path ( ref qpath @ hir:: QPath :: TypeRelative ( ..) ) => {
251
- let res = self . tables . qpath_res ( qpath, expr. hir_id ) ;
258
+ let res = self . tables ( ) . qpath_res ( qpath, expr. hir_id ) ;
252
259
self . handle_res ( res) ;
253
260
}
254
261
hir:: ExprKind :: MethodCall ( ..) => {
@@ -258,9 +265,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
258
265
self . handle_field_access ( & lhs, expr. hir_id ) ;
259
266
}
260
267
hir:: ExprKind :: Struct ( ref qpath, ref fields, _) => {
261
- let res = self . tables . qpath_res ( qpath, expr. hir_id ) ;
268
+ let res = self . tables ( ) . qpath_res ( qpath, expr. hir_id ) ;
262
269
self . handle_res ( res) ;
263
- if let ty:: Adt ( ref adt, _) = self . tables . expr_ty ( expr) . kind {
270
+ if let ty:: Adt ( ref adt, _) = self . tables ( ) . expr_ty ( expr) . kind {
264
271
self . mark_as_used_if_union ( adt, fields) ;
265
272
}
266
273
}
@@ -283,11 +290,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
283
290
fn visit_pat ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > ) {
284
291
match pat. kind {
285
292
PatKind :: Struct ( ref path, ref fields, _) => {
286
- let res = self . tables . qpath_res ( path, pat. hir_id ) ;
293
+ let res = self . tables ( ) . qpath_res ( path, pat. hir_id ) ;
287
294
self . handle_field_pattern_match ( pat, res, fields) ;
288
295
}
289
296
PatKind :: Path ( ref qpath) => {
290
- let res = self . tables . qpath_res ( qpath, pat. hir_id ) ;
297
+ let res = self . tables ( ) . qpath_res ( qpath, pat. hir_id ) ;
291
298
self . handle_res ( res) ;
292
299
}
293
300
_ => ( ) ,
@@ -473,7 +480,7 @@ fn find_live<'tcx>(
473
480
let mut symbol_visitor = MarkSymbolVisitor {
474
481
worklist,
475
482
tcx,
476
- tables : & ty :: TypeckTables :: empty ( None ) ,
483
+ maybe_typeck_tables : None ,
477
484
live_symbols : Default :: default ( ) ,
478
485
repr_has_repr_c : false ,
479
486
in_pat : false ,
0 commit comments