Skip to content

Commit 1b58ab7

Browse files
committed
rustc_passes/reachable: avoid using TypeckTables::empty for ReachableContext.
1 parent c49b664 commit 1b58ab7

File tree

2 files changed

+18
-10
lines changed

2 files changed

+18
-10
lines changed

src/librustc_passes/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#![feature(in_band_lifetimes)]
99
#![feature(nll)]
1010
#![feature(or_patterns)]
11+
#![cfg_attr(bootstrap, feature(track_caller))]
1112
#![recursion_limit = "256"]
1213

1314
#[macro_use]

src/librustc_passes/reachable.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)