Skip to content

Commit

Permalink
Auto merge of #36601 - jseyfried:build_reduced_graph_in_expansion, r=nrc
Browse files Browse the repository at this point in the history
Assign def ids and build the module graph during expansion

r? @nrc
  • Loading branch information
bors authored Sep 27, 2016
2 parents 322b553 + dfa69be commit a059cb2
Show file tree
Hide file tree
Showing 16 changed files with 321 additions and 281 deletions.
115 changes: 75 additions & 40 deletions src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,39 @@ use middle::cstore::InlinedItem;

use syntax::ast::*;
use syntax::visit;
use syntax::parse::token;
use syntax::parse::token::{self, keywords};

/// Creates def ids for nodes in the HIR.
pub struct DefCollector<'ast> {
pub struct DefCollector<'a> {
// If we are walking HIR (c.f., AST), we need to keep a reference to the
// crate.
hir_crate: Option<&'ast hir::Crate>,
definitions: &'ast mut Definitions,
hir_crate: Option<&'a hir::Crate>,
definitions: &'a mut Definitions,
parent_def: Option<DefIndex>,
pub visit_macro_invoc: Option<&'a mut FnMut(MacroInvocationData)>,
}

impl<'ast> DefCollector<'ast> {
pub fn new(definitions: &'ast mut Definitions) -> DefCollector<'ast> {
pub struct MacroInvocationData {
pub id: NodeId,
pub def_index: DefIndex,
pub const_integer: bool,
}

impl<'a> DefCollector<'a> {
pub fn new(definitions: &'a mut Definitions) -> Self {
DefCollector {
hir_crate: None,
definitions: definitions,
parent_def: None,
visit_macro_invoc: None,
}
}

pub fn extend(parent_node: NodeId,
parent_def_path: DefPath,
parent_def_id: DefId,
definitions: &'ast mut Definitions)
-> DefCollector<'ast> {
definitions: &'a mut Definitions)
-> Self {
let mut collector = DefCollector::new(definitions);

assert_eq!(parent_def_path.krate, parent_def_id.krate);
Expand All @@ -65,7 +73,7 @@ impl<'ast> DefCollector<'ast> {
self.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc);
}

pub fn walk_item(&mut self, ii: &'ast InlinedItem, krate: &'ast hir::Crate) {
pub fn walk_item(&mut self, ii: &'a InlinedItem, krate: &'a hir::Crate) {
self.hir_crate = Some(krate);
ii.visit(self);
}
Expand All @@ -84,29 +92,28 @@ impl<'ast> DefCollector<'ast> {
self.definitions.create_def_with_parent(parent, node_id, data)
}

fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
let parent = self.parent_def;
self.parent_def = Some(parent_def);
f(self);
self.parent_def = parent;
}

fn visit_ast_const_integer(&mut self, expr: &Expr) {
// Find the node which will be used after lowering.
if let ExprKind::Paren(ref inner) = expr.node {
return self.visit_ast_const_integer(inner);
}

// FIXME(eddyb) Closures should have separate
// function definition IDs and expression IDs.
if let ExprKind::Closure(..) = expr.node {
return;
pub fn visit_ast_const_integer(&mut self, expr: &Expr) {
match expr.node {
// Find the node which will be used after lowering.
ExprKind::Paren(ref inner) => return self.visit_ast_const_integer(inner),
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, true),
// FIXME(eddyb) Closures should have separate
// function definition IDs and expression IDs.
ExprKind::Closure(..) => return,
_ => {}
}

self.create_def(expr.id, DefPathData::Initializer);
}

fn visit_hir_const_integer(&mut self, expr: &'ast hir::Expr) {
fn visit_hir_const_integer(&mut self, expr: &hir::Expr) {
// FIXME(eddyb) Closures should have separate
// function definition IDs and expression IDs.
if let hir::ExprClosure(..) = expr.node {
Expand All @@ -115,9 +122,19 @@ impl<'ast> DefCollector<'ast> {

self.create_def(expr.id, DefPathData::Initializer);
}

fn visit_macro_invoc(&mut self, id: NodeId, const_integer: bool) {
if let Some(ref mut visit) = self.visit_macro_invoc {
visit(MacroInvocationData {
id: id,
const_integer: const_integer,
def_index: self.parent_def.unwrap(),
})
}
}
}

impl<'ast> visit::Visitor for DefCollector<'ast> {
impl<'a> visit::Visitor for DefCollector<'a> {
fn visit_item(&mut self, i: &Item) {
debug!("visit_item: {:?}", i);

Expand All @@ -129,10 +146,14 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) |
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
DefPathData::TypeNs(i.ident.name.as_str()),
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
return visit::walk_item(self, i);
}
ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_str()),
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
DefPathData::ValueNs(i.ident.name.as_str()),
ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name.as_str()),
ItemKind::Mac(..) if i.id == DUMMY_NODE_ID => return, // Scope placeholder
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
ItemKind::Use(..) => DefPathData::Misc,
};
let def = self.create_def(i.id, def_data);
Expand Down Expand Up @@ -198,7 +219,7 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
DefPathData::ValueNs(ti.ident.name.as_str()),
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name.as_str()),
TraitItemKind::Macro(..) => DefPathData::MacroDef(ti.ident.name.as_str()),
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
};

let def = self.create_def(ti.id, def_data);
Expand All @@ -216,7 +237,7 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
DefPathData::ValueNs(ii.ident.name.as_str()),
ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name.as_str()),
ImplItemKind::Macro(..) => DefPathData::MacroDef(ii.ident.name.as_str()),
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
};

let def = self.create_def(ii.id, def_data);
Expand All @@ -232,9 +253,13 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
fn visit_pat(&mut self, pat: &Pat) {
let parent_def = self.parent_def;

if let PatKind::Ident(_, id, _) = pat.node {
let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str()));
self.parent_def = Some(def);
match pat.node {
PatKind::Mac(..) => return self.visit_macro_invoc(pat.id, false),
PatKind::Ident(_, id, _) => {
let def = self.create_def(pat.id, DefPathData::Binding(id.node.name.as_str()));
self.parent_def = Some(def);
}
_ => {}
}

visit::walk_pat(self, pat);
Expand All @@ -244,25 +269,28 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
fn visit_expr(&mut self, expr: &Expr) {
let parent_def = self.parent_def;

if let ExprKind::Repeat(_, ref count) = expr.node {
self.visit_ast_const_integer(count);
}

if let ExprKind::Closure(..) = expr.node {
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
self.parent_def = Some(def);
match expr.node {
ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id, false),
ExprKind::Repeat(_, ref count) => self.visit_ast_const_integer(count),
ExprKind::Closure(..) => {
let def = self.create_def(expr.id, DefPathData::ClosureExpr);
self.parent_def = Some(def);
}
_ => {}
}

visit::walk_expr(self, expr);
self.parent_def = parent_def;
}

fn visit_ty(&mut self, ty: &Ty) {
if let TyKind::FixedLengthVec(_, ref length) = ty.node {
self.visit_ast_const_integer(length);
}
if let TyKind::ImplTrait(..) = ty.node {
self.create_def(ty.id, DefPathData::ImplTrait);
match ty.node {
TyKind::Mac(..) => return self.visit_macro_invoc(ty.id, false),
TyKind::FixedLengthVec(_, ref length) => self.visit_ast_const_integer(length),
TyKind::ImplTrait(..) => {
self.create_def(ty.id, DefPathData::ImplTrait);
}
_ => {}
}
visit::walk_ty(self, ty);
}
Expand All @@ -274,6 +302,13 @@ impl<'ast> visit::Visitor for DefCollector<'ast> {
fn visit_macro_def(&mut self, macro_def: &MacroDef) {
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name.as_str()));
}

fn visit_stmt(&mut self, stmt: &Stmt) {
match stmt.node {
StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id, false),
_ => visit::walk_stmt(self, stmt),
}
}
}

// We walk the HIR rather than the AST when reading items from metadata.
Expand Down
9 changes: 1 addition & 8 deletions src/librustc/hir/map/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
// except according to those terms.

use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
use hir::map::def_collector::DefCollector;
use rustc_data_structures::fnv::FnvHashMap;
use std::fmt::Write;
use std::hash::{Hash, Hasher, SipHasher};
use syntax::{ast, visit};
use syntax::ast;
use syntax::parse::token::{self, InternedString};
use ty::TyCtxt;
use util::nodemap::NodeMap;
Expand Down Expand Up @@ -224,12 +223,6 @@ impl Definitions {
}
}

pub fn collect(&mut self, krate: &ast::Crate) {
let mut def_collector = DefCollector::new(self);
def_collector.collect_root();
visit::walk_crate(&mut def_collector, krate);
}

/// Get the number of definitions.
pub fn len(&self) -> usize {
self.data.len()
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/map/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
pub use self::Node::*;
use self::MapEntry::*;
use self::collector::NodeCollector;
use self::def_collector::DefCollector;
pub use self::def_collector::{DefCollector, MacroInvocationData};
pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
DisambiguatedDefPathData, InlinedRootPath};

Expand Down
16 changes: 6 additions & 10 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,12 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
}
sess.track_errors(|| sess.lint_store.borrow_mut().process_command_line(sess))?;

// Currently, we ignore the name resolution data structures for the purposes of dependency
// tracking. Instead we will run name resolution and include its output in the hash of each
// item, much like we do for macro expansion. In other words, the hash reflects not just
// its contents but the results of name resolution on those contents. Hopefully we'll push
// this back at some point.
let _ignore = sess.dep_graph.in_ignore();
let mut crate_loader = CrateLoader::new(sess, &cstore, &krate, crate_name);
let resolver_arenas = Resolver::arenas();
let mut resolver =
Expand Down Expand Up @@ -733,9 +739,6 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
})
})?;

// Collect defintions for def ids.
time(sess.time_passes(), "collecting defs", || resolver.definitions.collect(&krate));

time(sess.time_passes(),
"early lint checks",
|| lint::check_ast_crate(sess, &krate));
Expand All @@ -745,13 +748,6 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
|| ast_validation::check_crate(sess, &krate));

time(sess.time_passes(), "name resolution", || -> CompileResult {
// Currently, we ignore the name resolution data structures for the purposes of dependency
// tracking. Instead we will run name resolution and include its output in the hash of each
// item, much like we do for macro expansion. In other words, the hash reflects not just
// its contents but the results of name resolution on those contents. Hopefully we'll push
// this back at some point.
let _ignore = sess.dep_graph.in_ignore();
resolver.build_reduced_graph(&krate);
resolver.resolve_imports();

// Since import resolution will eventually happen in expansion,
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_metadata/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,10 @@ Erroneous code examples:
```compile_fail,E0466
#[macro_use(a_macro(another_macro))] // error: invalid import declaration
extern crate some_crate;
extern crate core as some_crate;
#[macro_use(i_want = "some_macros")] // error: invalid import declaration
extern crate another_crate;
extern crate core as another_crate;
```
This is a syntax error at the level of attribute declarations. The proper
Expand Down Expand Up @@ -135,10 +135,10 @@ Erroneous code examples:
```compile_fail,E0467
#[macro_reexport] // error: no macros listed for export
extern crate macros_for_good;
extern crate core as macros_for_good;
#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
extern crate other_macros_for_good;
extern crate core as other_macros_for_good;
```
This is a syntax error at the level of attribute declarations.
Expand All @@ -165,8 +165,8 @@ Example of erroneous code:
```compile_fail,E0468
mod foo {
#[macro_use(helpful_macro)] // error: must be at crate root to import
extern crate some_crate; // macros from another crate
helpful_macro!(...)
extern crate core; // macros from another crate
helpful_macro!(...);
}
```
Expand Down
Loading

0 comments on commit a059cb2

Please sign in to comment.