@@ -60,10 +60,10 @@ fn method_might_be_inlined(
6060}
6161
6262// Information needed while computing reachability.
63- struct ReachableContext < ' a , ' tcx > {
63+ struct ReachableContext < ' tcx > {
6464 // The type context.
6565 tcx : TyCtxt < ' tcx > ,
66- tables : & ' a ty:: TypeckTables < ' tcx > ,
66+ maybe_typeck_tables : Option < & ' tcx ty:: TypeckTables < ' tcx > > ,
6767 // The set of items which must be exported in the linkage sense.
6868 reachable_symbols : HirIdSet ,
6969 // A worklist of item IDs. Each item ID in this worklist will be inlined
@@ -73,26 +73,25 @@ struct ReachableContext<'a, 'tcx> {
7373 any_library : bool ,
7474}
7575
76- impl < ' a , ' tcx > Visitor < ' tcx > for ReachableContext < ' a , ' tcx > {
76+ impl < ' tcx > Visitor < ' tcx > for ReachableContext < ' tcx > {
7777 type Map = intravisit:: ErasedMap < ' tcx > ;
7878
7979 fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
8080 NestedVisitorMap :: None
8181 }
8282
8383 fn visit_nested_body ( & mut self , body : hir:: BodyId ) {
84- let old_tables = self . tables ;
85- self . tables = self . tcx . body_tables ( body) ;
84+ let old_maybe_typeck_tables = self . maybe_typeck_tables . replace ( self . tcx . body_tables ( body) ) ;
8685 let body = self . tcx . hir ( ) . body ( body) ;
8786 self . visit_body ( body) ;
88- self . tables = old_tables ;
87+ self . maybe_typeck_tables = old_maybe_typeck_tables ;
8988 }
9089
9190 fn visit_expr ( & mut self , expr : & ' tcx hir:: Expr < ' tcx > ) {
9291 let res = match expr. kind {
93- hir:: ExprKind :: Path ( ref qpath) => Some ( self . tables . qpath_res ( qpath, expr. hir_id ) ) ,
92+ hir:: ExprKind :: Path ( ref qpath) => Some ( self . tables ( ) . qpath_res ( qpath, expr. hir_id ) ) ,
9493 hir:: ExprKind :: MethodCall ( ..) => self
95- . tables
94+ . tables ( )
9695 . type_dependent_def ( expr. hir_id )
9796 . map ( |( kind, def_id) | Res :: Def ( kind, def_id) ) ,
9897 _ => None ,
@@ -133,7 +132,15 @@ impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
133132 }
134133}
135134
136- impl < ' a , ' tcx > ReachableContext < ' a , ' tcx > {
135+ impl < ' tcx > ReachableContext < ' tcx > {
136+ /// Gets the type-checking side-tables for the current body.
137+ /// As this will ICE if called outside bodies, only call when working with
138+ /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies).
139+ #[ track_caller]
140+ fn tables ( & self ) -> & ' tcx ty:: TypeckTables < ' tcx > {
141+ self . maybe_typeck_tables . expect ( "`ReachableContext::tables` called outside of body" )
142+ }
143+
137144 // Returns true if the given def ID represents a local item that is
138145 // eligible for inlining and false otherwise.
139146 fn def_id_represents_local_inlined_item ( & self , def_id : DefId ) -> bool {
@@ -381,7 +388,7 @@ fn reachable_set<'tcx>(tcx: TyCtxt<'tcx>, crate_num: CrateNum) -> &'tcx HirIdSet
381388 } ) ;
382389 let mut reachable_context = ReachableContext {
383390 tcx,
384- tables : & ty :: TypeckTables :: empty ( None ) ,
391+ maybe_typeck_tables : None ,
385392 reachable_symbols : Default :: default ( ) ,
386393 worklist : Vec :: new ( ) ,
387394 any_library,
0 commit comments