From 883ece499fef22b4703f5b04133bb2beff08c794 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 25 Jun 2020 20:58:33 +0300 Subject: [PATCH] rustc_passes/dead: avoid using TypeckTables::empty for MarkSymbolVisitor. --- src/librustc_passes/dead.rs | 45 +++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index 503fbb64db83..87348894a5ad 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -37,10 +37,10 @@ fn should_explore(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { } } -struct MarkSymbolVisitor<'a, 'tcx> { +struct MarkSymbolVisitor<'tcx> { worklist: Vec, tcx: TyCtxt<'tcx>, - tables: &'a ty::TypeckTables<'tcx>, + maybe_typeck_tables: Option<&'tcx ty::TypeckTables<'tcx>>, live_symbols: FxHashSet, repr_has_repr_c: bool, in_pat: bool, @@ -50,7 +50,15 @@ struct MarkSymbolVisitor<'a, 'tcx> { struct_constructors: FxHashMap, } -impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { +impl<'tcx> MarkSymbolVisitor<'tcx> { + /// Gets the type-checking side-tables for the current body. + /// As this will ICE if called outside bodies, only call when working with + /// `Expr` or `Pat` nodes (they are guaranteed to be found only in bodies). + #[track_caller] + fn tables(&self) -> &'tcx ty::TypeckTables<'tcx> { + self.maybe_typeck_tables.expect("`MarkSymbolVisitor::tables` called outside of body") + } + fn check_def_id(&mut self, def_id: DefId) { if let Some(def_id) = def_id.as_local() { let hir_id = self.tcx.hir().as_local_hir_id(def_id); @@ -107,7 +115,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn lookup_and_handle_method(&mut self, id: hir::HirId) { - if let Some(def_id) = self.tables.type_dependent_def_id(id) { + if let Some(def_id) = self.tables().type_dependent_def_id(id) { self.check_def_id(def_id); } else { bug!("no type-dependent def for method"); @@ -115,9 +123,9 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { } fn handle_field_access(&mut self, lhs: &hir::Expr<'_>, hir_id: hir::HirId) { - match self.tables.expr_ty_adjusted(lhs).kind { + match self.tables().expr_ty_adjusted(lhs).kind { ty::Adt(def, _) => { - let index = self.tcx.field_index(hir_id, self.tables); + let index = self.tcx.field_index(hir_id, self.tables()); self.insert_def_id(def.non_enum_variant().fields[index].did); } ty::Tuple(..) => {} @@ -131,7 +139,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { res: Res, pats: &[hir::FieldPat<'_>], ) { - let variant = match self.tables.node_type(lhs.hir_id).kind { + let variant = match self.tables().node_type(lhs.hir_id).kind { ty::Adt(adt, _) => adt.variant_of_res(res), _ => span_bug!(lhs.span, "non-ADT in struct pattern"), }; @@ -139,7 +147,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { if let PatKind::Wild = pat.pat.kind { continue; } - let index = self.tcx.field_index(pat.hir_id, self.tables); + let index = self.tcx.field_index(pat.hir_id, self.tables()); self.insert_def_id(variant.fields[index].did); } } @@ -204,14 +212,14 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { fn mark_as_used_if_union(&mut self, adt: &ty::AdtDef, fields: &[hir::Field<'_>]) { if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did.is_local() { for field in fields { - let index = self.tcx.field_index(field.hir_id, self.tables); + let index = self.tcx.field_index(field.hir_id, self.tables()); self.insert_def_id(adt.non_enum_variant().fields[index].did); } } } } -impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { +impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> { type Map = intravisit::ErasedMap<'tcx>; fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { @@ -219,11 +227,10 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { } fn visit_nested_body(&mut self, body: hir::BodyId) { - let old_tables = self.tables; - self.tables = self.tcx.body_tables(body); + let old_maybe_typeck_tables = self.maybe_typeck_tables.replace(self.tcx.body_tables(body)); let body = self.tcx.hir().body(body); self.visit_body(body); - self.tables = old_tables; + self.maybe_typeck_tables = old_maybe_typeck_tables; } fn visit_variant_data( @@ -248,7 +255,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) { match expr.kind { hir::ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(..)) => { - let res = self.tables.qpath_res(qpath, expr.hir_id); + let res = self.tables().qpath_res(qpath, expr.hir_id); self.handle_res(res); } hir::ExprKind::MethodCall(..) => { @@ -258,9 +265,9 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { self.handle_field_access(&lhs, expr.hir_id); } hir::ExprKind::Struct(ref qpath, ref fields, _) => { - let res = self.tables.qpath_res(qpath, expr.hir_id); + let res = self.tables().qpath_res(qpath, expr.hir_id); self.handle_res(res); - if let ty::Adt(ref adt, _) = self.tables.expr_ty(expr).kind { + if let ty::Adt(ref adt, _) = self.tables().expr_ty(expr).kind { self.mark_as_used_if_union(adt, fields); } } @@ -283,11 +290,11 @@ impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> { fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) { match pat.kind { PatKind::Struct(ref path, ref fields, _) => { - let res = self.tables.qpath_res(path, pat.hir_id); + let res = self.tables().qpath_res(path, pat.hir_id); self.handle_field_pattern_match(pat, res, fields); } PatKind::Path(ref qpath) => { - let res = self.tables.qpath_res(qpath, pat.hir_id); + let res = self.tables().qpath_res(qpath, pat.hir_id); self.handle_res(res); } _ => (), @@ -473,7 +480,7 @@ fn find_live<'tcx>( let mut symbol_visitor = MarkSymbolVisitor { worklist, tcx, - tables: &ty::TypeckTables::empty(None), + maybe_typeck_tables: None, live_symbols: Default::default(), repr_has_repr_c: false, in_pat: false,