Skip to content

Commit cbf8873

Browse files
committed
Auto merge of #38813 - eddyb:lazy-11, r=nikomatsakis
[11/n] Separate ty::Tables into one per each body. _This is part of a series ([prev](#38449) | [next]()) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well. If any motivation is unclear, please ask for additional PR description clarifications or code comments._ <hr> In order to track the results of type-checking and inference for incremental recompilation, they must be stored separately for each function or constant value, instead of lumped together. These side-`Tables` also have to be tracked by various passes, as they visit through bodies (all of which have `Tables`, even if closures share the ones from their parent functions). This is usually done by switching a `tables` field in an override of `visit_nested_body` before recursing through `visit_body`, to the relevant one and then restoring it - however, in many cases the nesting is unnecessary and creating the visitor for each body in the crate and then visiting that body, would be a much cleaner solution. To simplify handling of inlined HIR & its side-tables, their `NodeId` remapping and entries HIR map were fully stripped out, which means that `NodeId`s from inlined HIR must not be used where a local `NodeId` is expected. It might be possible to make the nodes (`Expr`, `Block`, `Pat`, etc.) that only show up within a `Body` have IDs that are scoped to that `Body`, which would also allow `Tables` to use `Vec`s. That last part also fixes #38790 which was accidentally introduced in a previous refactor.
2 parents 7ac9d33 + cde0a7e commit cbf8873

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1120
-1407
lines changed

src/Cargo.lock

-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc/cfg/construct.rs

+19-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use hir::{self, PatKind};
1818

1919
struct CFGBuilder<'a, 'tcx: 'a> {
2020
tcx: TyCtxt<'a, 'tcx, 'tcx>,
21+
tables: &'a ty::Tables<'tcx>,
2122
graph: CFGGraph,
2223
fn_exit: CFGIndex,
2324
loop_scopes: Vec<LoopScope>,
@@ -42,10 +43,23 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
4243
let fn_exit = graph.add_node(CFGNodeData::Exit);
4344
let body_exit;
4445

46+
// Find the function this expression is from.
47+
let mut node_id = body.id;
48+
loop {
49+
let node = tcx.map.get(node_id);
50+
if hir::map::blocks::FnLikeNode::from_node(node).is_some() {
51+
break;
52+
}
53+
let parent = tcx.map.get_parent_node(node_id);
54+
assert!(node_id != parent);
55+
node_id = parent;
56+
}
57+
4558
let mut cfg_builder = CFGBuilder {
59+
tcx: tcx,
60+
tables: tcx.item_tables(tcx.map.local_def_id(node_id)),
4661
graph: graph,
4762
fn_exit: fn_exit,
48-
tcx: tcx,
4963
loop_scopes: Vec::new()
5064
};
5165
body_exit = cfg_builder.expr(body, entry);
@@ -310,11 +324,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
310324
}
311325

312326
hir::ExprIndex(ref l, ref r) |
313-
hir::ExprBinary(_, ref l, ref r) if self.tcx.tables().is_method_call(expr.id) => {
327+
hir::ExprBinary(_, ref l, ref r) if self.tables.is_method_call(expr.id) => {
314328
self.call(expr, pred, &l, Some(&**r).into_iter())
315329
}
316330

317-
hir::ExprUnary(_, ref e) if self.tcx.tables().is_method_call(expr.id) => {
331+
hir::ExprUnary(_, ref e) if self.tables.is_method_call(expr.id) => {
318332
self.call(expr, pred, &e, None::<hir::Expr>.iter())
319333
}
320334

@@ -368,9 +382,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
368382
func_or_rcvr: &hir::Expr,
369383
args: I) -> CFGIndex {
370384
let method_call = ty::MethodCall::expr(call_expr.id);
371-
let fn_ty = match self.tcx.tables().method_map.get(&method_call) {
385+
let fn_ty = match self.tables.method_map.get(&method_call) {
372386
Some(method) => method.ty,
373-
None => self.tcx.tables().expr_ty_adjusted(func_or_rcvr)
387+
None => self.tables.expr_ty_adjusted(func_or_rcvr)
374388
};
375389

376390
let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);

src/librustc/dep_graph/dep_node.rs

+3
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub enum DepNode<D: Clone + Debug> {
113113
SizedConstraint(D),
114114
AssociatedItemDefIds(D),
115115
InherentImpls(D),
116+
Tables(D),
116117

117118
// The set of impls for a given trait. Ultimately, it would be
118119
// nice to get more fine-grained here (e.g., to include a
@@ -162,6 +163,7 @@ impl<D: Clone + Debug> DepNode<D> {
162163
ItemSignature,
163164
AssociatedItemDefIds,
164165
InherentImpls,
166+
Tables,
165167
TraitImpls,
166168
ReprHints,
167169
}
@@ -230,6 +232,7 @@ impl<D: Clone + Debug> DepNode<D> {
230232
SizedConstraint(ref d) => op(d).map(SizedConstraint),
231233
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
232234
InherentImpls(ref d) => op(d).map(InherentImpls),
235+
Tables(ref d) => op(d).map(Tables),
233236
TraitImpls(ref d) => op(d).map(TraitImpls),
234237
TraitItems(ref d) => op(d).map(TraitItems),
235238
ReprHints(ref d) => op(d).map(ReprHints),

src/librustc/hir/map/blocks.rs

-19
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,6 @@ pub struct FnLikeNode<'a> { node: map::Node<'a> }
4545
/// corresponds to some FnLikeNode.
4646
pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
4747

48-
/// Components shared by fn-like things (fn items, methods, closures).
49-
pub struct FnParts<'a> {
50-
pub decl: &'a FnDecl,
51-
pub body: ast::BodyId,
52-
pub kind: FnKind<'a>,
53-
pub span: Span,
54-
pub id: NodeId,
55-
}
56-
5748
impl MaybeFnLike for ast::Item {
5849
fn is_fn_like(&self) -> bool {
5950
match self.node { ast::ItemFn(..) => true, _ => false, }
@@ -165,16 +156,6 @@ impl<'a> FnLikeNode<'a> {
165156
}
166157
}
167158

168-
pub fn to_fn_parts(self) -> FnParts<'a> {
169-
FnParts {
170-
decl: self.decl(),
171-
body: self.body(),
172-
kind: self.kind(),
173-
span: self.span(),
174-
id: self.id(),
175-
}
176-
}
177-
178159
pub fn body(self) -> ast::BodyId {
179160
self.handle(|i: ItemFnParts<'a>| i.body,
180161
|_, _, _: &'a ast::MethodSig, _, body: ast::BodyId, _, _| body,

src/librustc/hir/map/collector.rs

+4-34
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@ pub struct NodeCollector<'ast> {
2323
pub(super) map: Vec<MapEntry<'ast>>,
2424
/// The parent of this node
2525
pub parent_node: NodeId,
26-
/// If true, completely ignore nested items. We set this when loading
27-
/// HIR from metadata, since in that case we only want the HIR for
28-
/// one specific item (and not the ones nested inside of it).
29-
pub ignore_nested_items: bool
3026
}
3127

3228
impl<'ast> NodeCollector<'ast> {
@@ -35,30 +31,12 @@ impl<'ast> NodeCollector<'ast> {
3531
krate: krate,
3632
map: vec![],
3733
parent_node: CRATE_NODE_ID,
38-
ignore_nested_items: false
3934
};
4035
collector.insert_entry(CRATE_NODE_ID, RootCrate);
4136

4237
collector
4338
}
4439

45-
pub(super) fn extend(krate: &'ast Crate,
46-
parent: &'ast InlinedItem,
47-
parent_node: NodeId,
48-
map: Vec<MapEntry<'ast>>)
49-
-> NodeCollector<'ast> {
50-
let mut collector = NodeCollector {
51-
krate: krate,
52-
map: map,
53-
parent_node: parent_node,
54-
ignore_nested_items: true
55-
};
56-
57-
collector.insert_entry(parent_node, RootInlinedParent(parent));
58-
59-
collector
60-
}
61-
6240
fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
6341
debug!("ast_map: {:?} => {:?}", id, entry);
6442
let len = self.map.len();
@@ -92,27 +70,19 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
9270

9371
fn visit_nested_item(&mut self, item: ItemId) {
9472
debug!("visit_nested_item: {:?}", item);
95-
if !self.ignore_nested_items {
96-
self.visit_item(self.krate.item(item.id))
97-
}
73+
self.visit_item(self.krate.item(item.id));
9874
}
9975

10076
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
101-
if !self.ignore_nested_items {
102-
self.visit_trait_item(self.krate.trait_item(item_id))
103-
}
77+
self.visit_trait_item(self.krate.trait_item(item_id));
10478
}
10579

10680
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
107-
if !self.ignore_nested_items {
108-
self.visit_impl_item(self.krate.impl_item(item_id))
109-
}
81+
self.visit_impl_item(self.krate.impl_item(item_id));
11082
}
11183

11284
fn visit_nested_body(&mut self, id: BodyId) {
113-
if !self.ignore_nested_items {
114-
self.visit_body(self.krate.body(id))
115-
}
85+
self.visit_body(self.krate.body(id));
11686
}
11787

11888
fn visit_item(&mut self, i: &'ast Item) {

0 commit comments

Comments
 (0)