@@ -37,10 +37,10 @@ fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
3737 }
3838}
3939
40- struct MarkSymbolVisitor < ' a , ' tcx > {
40+ struct MarkSymbolVisitor < ' tcx > {
4141 worklist : Vec < hir:: HirId > ,
4242 tcx : TyCtxt < ' tcx > ,
43- tables : & ' a ty:: TypeckTables < ' tcx > ,
43+ maybe_typeck_tables : Option < & ' tcx ty:: TypeckTables < ' tcx > > ,
4444 live_symbols : FxHashSet < hir:: HirId > ,
4545 repr_has_repr_c : bool ,
4646 in_pat : bool ,
@@ -50,7 +50,15 @@ struct MarkSymbolVisitor<'a, 'tcx> {
5050 struct_constructors : FxHashMap < hir:: HirId , hir:: HirId > ,
5151}
5252
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+
5462 fn check_def_id ( & mut self , def_id : DefId ) {
5563 if let Some ( def_id) = def_id. as_local ( ) {
5664 let hir_id = self . tcx . hir ( ) . as_local_hir_id ( def_id) ;
@@ -107,17 +115,17 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
107115 }
108116
109117 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) {
111119 self . check_def_id ( def_id) ;
112120 } else {
113121 bug ! ( "no type-dependent def for method" ) ;
114122 }
115123 }
116124
117125 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 {
119127 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 ( ) ) ;
121129 self . insert_def_id ( def. non_enum_variant ( ) . fields [ index] . did ) ;
122130 }
123131 ty:: Tuple ( ..) => { }
@@ -131,15 +139,15 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
131139 res : Res ,
132140 pats : & [ hir:: FieldPat < ' _ > ] ,
133141 ) {
134- let variant = match self . tables . node_type ( lhs. hir_id ) . kind {
142+ let variant = match self . tables ( ) . node_type ( lhs. hir_id ) . kind {
135143 ty:: Adt ( adt, _) => adt. variant_of_res ( res) ,
136144 _ => span_bug ! ( lhs. span, "non-ADT in struct pattern" ) ,
137145 } ;
138146 for pat in pats {
139147 if let PatKind :: Wild = pat. pat . kind {
140148 continue ;
141149 }
142- let index = self . tcx . field_index ( pat. hir_id , self . tables ) ;
150+ let index = self . tcx . field_index ( pat. hir_id , self . tables ( ) ) ;
143151 self . insert_def_id ( variant. fields [ index] . did ) ;
144152 }
145153 }
@@ -204,26 +212,25 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
204212 fn mark_as_used_if_union ( & mut self , adt : & ty:: AdtDef , fields : & [ hir:: Field < ' _ > ] ) {
205213 if adt. is_union ( ) && adt. non_enum_variant ( ) . fields . len ( ) > 1 && adt. did . is_local ( ) {
206214 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 ( ) ) ;
208216 self . insert_def_id ( adt. non_enum_variant ( ) . fields [ index] . did ) ;
209217 }
210218 }
211219 }
212220}
213221
214- impl < ' a , ' tcx > Visitor < ' tcx > for MarkSymbolVisitor < ' a , ' tcx > {
222+ impl < ' tcx > Visitor < ' tcx > for MarkSymbolVisitor < ' tcx > {
215223 type Map = intravisit:: ErasedMap < ' tcx > ;
216224
217225 fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
218226 NestedVisitorMap :: None
219227 }
220228
221229 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) ) ;
224231 let body = self . tcx . hir ( ) . body ( body) ;
225232 self . visit_body ( body) ;
226- self . tables = old_tables ;
233+ self . maybe_typeck_tables = old_maybe_typeck_tables ;
227234 }
228235
229236 fn visit_variant_data (
@@ -248,7 +255,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
248255 fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr < ' tcx > ) {
249256 match expr. kind {
250257 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 ) ;
252259 self . handle_res ( res) ;
253260 }
254261 hir:: ExprKind :: MethodCall ( ..) => {
@@ -258,9 +265,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
258265 self . handle_field_access ( & lhs, expr. hir_id ) ;
259266 }
260267 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 ) ;
262269 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 {
264271 self . mark_as_used_if_union ( adt, fields) ;
265272 }
266273 }
@@ -283,11 +290,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
283290 fn visit_pat ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > ) {
284291 match pat. kind {
285292 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 ) ;
287294 self . handle_field_pattern_match ( pat, res, fields) ;
288295 }
289296 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 ) ;
291298 self . handle_res ( res) ;
292299 }
293300 _ => ( ) ,
@@ -473,7 +480,7 @@ fn find_live<'tcx>(
473480 let mut symbol_visitor = MarkSymbolVisitor {
474481 worklist,
475482 tcx,
476- tables : & ty :: TypeckTables :: empty ( None ) ,
483+ maybe_typeck_tables : None ,
477484 live_symbols : Default :: default ( ) ,
478485 repr_has_repr_c : false ,
479486 in_pat : false ,
0 commit comments