Skip to content

Commit

Permalink
Auto merge of #38813 - eddyb:lazy-11, r=nikomatsakis
Browse files Browse the repository at this point in the history
[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.
  • Loading branch information
bors committed Jan 8, 2017
2 parents 7ac9d33 + cde0a7e commit cbf8873
Show file tree
Hide file tree
Showing 76 changed files with 1,120 additions and 1,407 deletions.
1 change: 0 additions & 1 deletion src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 19 additions & 5 deletions src/librustc/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use hir::{self, PatKind};

struct CFGBuilder<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
tables: &'a ty::Tables<'tcx>,
graph: CFGGraph,
fn_exit: CFGIndex,
loop_scopes: Vec<LoopScope>,
Expand All @@ -42,10 +43,23 @@ pub fn construct<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let fn_exit = graph.add_node(CFGNodeData::Exit);
let body_exit;

// Find the function this expression is from.
let mut node_id = body.id;
loop {
let node = tcx.map.get(node_id);
if hir::map::blocks::FnLikeNode::from_node(node).is_some() {
break;
}
let parent = tcx.map.get_parent_node(node_id);
assert!(node_id != parent);
node_id = parent;
}

let mut cfg_builder = CFGBuilder {
tcx: tcx,
tables: tcx.item_tables(tcx.map.local_def_id(node_id)),
graph: graph,
fn_exit: fn_exit,
tcx: tcx,
loop_scopes: Vec::new()
};
body_exit = cfg_builder.expr(body, entry);
Expand Down Expand Up @@ -310,11 +324,11 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
}

hir::ExprIndex(ref l, ref r) |
hir::ExprBinary(_, ref l, ref r) if self.tcx.tables().is_method_call(expr.id) => {
hir::ExprBinary(_, ref l, ref r) if self.tables.is_method_call(expr.id) => {
self.call(expr, pred, &l, Some(&**r).into_iter())
}

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

Expand Down Expand Up @@ -368,9 +382,9 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
func_or_rcvr: &hir::Expr,
args: I) -> CFGIndex {
let method_call = ty::MethodCall::expr(call_expr.id);
let fn_ty = match self.tcx.tables().method_map.get(&method_call) {
let fn_ty = match self.tables.method_map.get(&method_call) {
Some(method) => method.ty,
None => self.tcx.tables().expr_ty_adjusted(func_or_rcvr)
None => self.tables.expr_ty_adjusted(func_or_rcvr)
};

let func_or_rcvr_exit = self.expr(func_or_rcvr, pred);
Expand Down
3 changes: 3 additions & 0 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub enum DepNode<D: Clone + Debug> {
SizedConstraint(D),
AssociatedItemDefIds(D),
InherentImpls(D),
Tables(D),

// The set of impls for a given trait. Ultimately, it would be
// nice to get more fine-grained here (e.g., to include a
Expand Down Expand Up @@ -162,6 +163,7 @@ impl<D: Clone + Debug> DepNode<D> {
ItemSignature,
AssociatedItemDefIds,
InherentImpls,
Tables,
TraitImpls,
ReprHints,
}
Expand Down Expand Up @@ -230,6 +232,7 @@ impl<D: Clone + Debug> DepNode<D> {
SizedConstraint(ref d) => op(d).map(SizedConstraint),
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
InherentImpls(ref d) => op(d).map(InherentImpls),
Tables(ref d) => op(d).map(Tables),
TraitImpls(ref d) => op(d).map(TraitImpls),
TraitItems(ref d) => op(d).map(TraitItems),
ReprHints(ref d) => op(d).map(ReprHints),
Expand Down
19 changes: 0 additions & 19 deletions src/librustc/hir/map/blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,6 @@ pub struct FnLikeNode<'a> { node: map::Node<'a> }
/// corresponds to some FnLikeNode.
pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }

/// Components shared by fn-like things (fn items, methods, closures).
pub struct FnParts<'a> {
pub decl: &'a FnDecl,
pub body: ast::BodyId,
pub kind: FnKind<'a>,
pub span: Span,
pub id: NodeId,
}

impl MaybeFnLike for ast::Item {
fn is_fn_like(&self) -> bool {
match self.node { ast::ItemFn(..) => true, _ => false, }
Expand Down Expand Up @@ -165,16 +156,6 @@ impl<'a> FnLikeNode<'a> {
}
}

pub fn to_fn_parts(self) -> FnParts<'a> {
FnParts {
decl: self.decl(),
body: self.body(),
kind: self.kind(),
span: self.span(),
id: self.id(),
}
}

pub fn body(self) -> ast::BodyId {
self.handle(|i: ItemFnParts<'a>| i.body,
|_, _, _: &'a ast::MethodSig, _, body: ast::BodyId, _, _| body,
Expand Down
38 changes: 4 additions & 34 deletions src/librustc/hir/map/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ pub struct NodeCollector<'ast> {
pub(super) map: Vec<MapEntry<'ast>>,
/// The parent of this node
pub parent_node: NodeId,
/// If true, completely ignore nested items. We set this when loading
/// HIR from metadata, since in that case we only want the HIR for
/// one specific item (and not the ones nested inside of it).
pub ignore_nested_items: bool
}

impl<'ast> NodeCollector<'ast> {
Expand All @@ -35,30 +31,12 @@ impl<'ast> NodeCollector<'ast> {
krate: krate,
map: vec![],
parent_node: CRATE_NODE_ID,
ignore_nested_items: false
};
collector.insert_entry(CRATE_NODE_ID, RootCrate);

collector
}

pub(super) fn extend(krate: &'ast Crate,
parent: &'ast InlinedItem,
parent_node: NodeId,
map: Vec<MapEntry<'ast>>)
-> NodeCollector<'ast> {
let mut collector = NodeCollector {
krate: krate,
map: map,
parent_node: parent_node,
ignore_nested_items: true
};

collector.insert_entry(parent_node, RootInlinedParent(parent));

collector
}

fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
debug!("ast_map: {:?} => {:?}", id, entry);
let len = self.map.len();
Expand Down Expand Up @@ -92,27 +70,19 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {

fn visit_nested_item(&mut self, item: ItemId) {
debug!("visit_nested_item: {:?}", item);
if !self.ignore_nested_items {
self.visit_item(self.krate.item(item.id))
}
self.visit_item(self.krate.item(item.id));
}

fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
if !self.ignore_nested_items {
self.visit_trait_item(self.krate.trait_item(item_id))
}
self.visit_trait_item(self.krate.trait_item(item_id));
}

fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
if !self.ignore_nested_items {
self.visit_impl_item(self.krate.impl_item(item_id))
}
self.visit_impl_item(self.krate.impl_item(item_id));
}

fn visit_nested_body(&mut self, id: BodyId) {
if !self.ignore_nested_items {
self.visit_body(self.krate.body(id))
}
self.visit_body(self.krate.body(id));
}

fn visit_item(&mut self, i: &'ast Item) {
Expand Down
Loading

0 comments on commit cbf8873

Please sign in to comment.