Build the reduced graph during expansion.
This commit is contained in:
parent
ebaaafcd5d
commit
b3a81ee844
src
@ -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 =
|
||||
@ -742,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,
|
||||
|
@ -31,8 +31,7 @@ use syntax::ast::Name;
|
||||
use syntax::attr;
|
||||
use syntax::parse::token;
|
||||
|
||||
use syntax::ast::{Block, Crate};
|
||||
use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
|
||||
use syntax::ast::{self, Block, ForeignItem, ForeignItemKind, Item, ItemKind};
|
||||
use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
|
||||
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use syntax::parse::token::keywords;
|
||||
@ -53,11 +52,6 @@ impl<'a> ToNameBinding<'a> for (Def, Span, ty::Visibility) {
|
||||
}
|
||||
|
||||
impl<'b> Resolver<'b> {
|
||||
/// Constructs the reduced graph for the entire crate.
|
||||
pub fn build_reduced_graph(&mut self, krate: &Crate) {
|
||||
visit::walk_crate(&mut BuildReducedGraphVisitor { resolver: self }, krate);
|
||||
}
|
||||
|
||||
/// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined;
|
||||
/// otherwise, reports an error.
|
||||
fn define<T>(&mut self, parent: Module<'b>, name: Name, ns: Namespace, def: T)
|
||||
@ -72,7 +66,7 @@ impl<'b> Resolver<'b> {
|
||||
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
|
||||
// If any statements are items, we need to create an anonymous module
|
||||
block.stmts.iter().any(|statement| match statement.node {
|
||||
StmtKind::Item(_) => true,
|
||||
StmtKind::Item(_) | StmtKind::Mac(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
@ -206,6 +200,8 @@ impl<'b> Resolver<'b> {
|
||||
}
|
||||
}
|
||||
|
||||
ItemKind::Mod(..) if item.ident == keywords::Invalid.ident() => {} // Crate root
|
||||
|
||||
ItemKind::Mod(..) => {
|
||||
let def = Def::Mod(self.definitions.local_def_id(item.id));
|
||||
let module = self.arenas.alloc_module(ModuleS {
|
||||
@ -478,12 +474,42 @@ impl<'b> Resolver<'b> {
|
||||
}
|
||||
}
|
||||
|
||||
struct BuildReducedGraphVisitor<'a, 'b: 'a> {
|
||||
resolver: &'a mut Resolver<'b>,
|
||||
pub struct BuildReducedGraphVisitor<'a, 'b: 'a> {
|
||||
pub resolver: &'a mut Resolver<'b>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
fn visit_invoc(&mut self, id: ast::NodeId) {
|
||||
self.resolver.expansion_data.get_mut(&id.as_u32()).unwrap().module2 =
|
||||
self.resolver.current_module;
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! method {
|
||||
($visit:ident: $ty:ty, $invoc:path, $walk:ident) => {
|
||||
fn $visit(&mut self, node: &$ty) {
|
||||
match node.node {
|
||||
$invoc(..) => self.visit_invoc(node.id),
|
||||
_ => visit::$walk(self, node),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
|
||||
method!(visit_impl_item: ast::ImplItem, ast::ImplItemKind::Macro, walk_impl_item);
|
||||
method!(visit_stmt: ast::Stmt, ast::StmtKind::Mac, walk_stmt);
|
||||
method!(visit_expr: ast::Expr, ast::ExprKind::Mac, walk_expr);
|
||||
method!(visit_pat: ast::Pat, ast::PatKind::Mac, walk_pat);
|
||||
method!(visit_ty: ast::Ty, ast::TyKind::Mac, walk_ty);
|
||||
|
||||
fn visit_item(&mut self, item: &Item) {
|
||||
match item.node {
|
||||
ItemKind::Mac(..) if item.id == ast::DUMMY_NODE_ID => return, // Scope placeholder
|
||||
ItemKind::Mac(..) => return self.visit_invoc(item.id),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let parent = self.resolver.current_module;
|
||||
self.resolver.build_reduced_graph_for_item(item);
|
||||
visit::walk_item(self, item);
|
||||
@ -492,6 +518,7 @@ impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
|
||||
|
||||
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
|
||||
self.resolver.build_reduced_graph_for_foreign_item(foreign_item);
|
||||
visit::walk_foreign_item(self, foreign_item);
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, block: &Block) {
|
||||
@ -515,7 +542,7 @@ impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
|
||||
(Def::Method(item_def_id), ValueNS)
|
||||
}
|
||||
TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
|
||||
TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
|
||||
TraitItemKind::Macro(_) => return self.visit_invoc(item.id),
|
||||
};
|
||||
|
||||
self.resolver.trait_item_map.insert((item.ident.name, def_id), is_static_method);
|
||||
|
@ -1074,7 +1074,7 @@ pub struct Resolver<'a> {
|
||||
macro_names: FnvHashSet<Name>,
|
||||
|
||||
// Maps the `Mark` of an expansion to its containing module or block.
|
||||
expansion_data: FnvHashMap<u32, macros::ExpansionData>,
|
||||
expansion_data: FnvHashMap<u32, macros::ExpansionData<'a>>,
|
||||
}
|
||||
|
||||
pub struct ResolverArenas<'a> {
|
||||
@ -1192,7 +1192,7 @@ impl<'a> Resolver<'a> {
|
||||
DefCollector::new(&mut definitions).collect_root();
|
||||
|
||||
let mut expansion_data = FnvHashMap();
|
||||
expansion_data.insert(0, macros::ExpansionData::root()); // Crate root expansion
|
||||
expansion_data.insert(0, macros::ExpansionData::root(graph_root)); // Crate root expansion
|
||||
|
||||
Resolver {
|
||||
session: session,
|
||||
|
@ -8,7 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use Resolver;
|
||||
use {Module, Resolver};
|
||||
use build_reduced_graph::BuildReducedGraphVisitor;
|
||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
|
||||
use rustc::hir::map::DefCollector;
|
||||
use rustc::middle::cstore::LoadedMacro;
|
||||
@ -30,16 +31,18 @@ use syntax::visit::{self, Visitor};
|
||||
use syntax_pos::Span;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ExpansionData {
|
||||
pub struct ExpansionData<'a> {
|
||||
module: Rc<ModuleData>,
|
||||
def_index: DefIndex,
|
||||
pub module2: Module<'a>,
|
||||
}
|
||||
|
||||
impl ExpansionData {
|
||||
pub fn root() -> Self {
|
||||
impl<'a> ExpansionData<'a> {
|
||||
pub fn root(graph_root: Module<'a>) -> Self {
|
||||
ExpansionData {
|
||||
module: Default::default(),
|
||||
def_index: CRATE_DEF_INDEX,
|
||||
module2: graph_root,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -58,10 +61,14 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||
}
|
||||
|
||||
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
|
||||
let module = self.expansion_data[&mark.as_u32()].module.clone();
|
||||
let mut visitor = ExpansionVisitor { current_module: module, resolver: self };
|
||||
let expansion_data = self.expansion_data[&mark.as_u32()].clone();
|
||||
self.current_module = expansion_data.module2;
|
||||
let mut visitor =
|
||||
ExpansionVisitor { current_module: expansion_data.module, resolver: self };
|
||||
|
||||
visitor.collect_def_ids(mark, expansion);
|
||||
expansion.visit_with(&mut visitor);
|
||||
expansion.visit_with(&mut BuildReducedGraphVisitor { resolver: visitor.resolver });
|
||||
}
|
||||
|
||||
fn add_macro(&mut self, scope: Mark, mut def: ast::MacroDef) {
|
||||
@ -210,11 +217,13 @@ impl<'a, 'b> ExpansionVisitor<'a, 'b> {
|
||||
fn collect_def_ids(&mut self, mark: Mark, expansion: &Expansion) {
|
||||
let expansion_data = &mut self.resolver.expansion_data;
|
||||
let module = &self.current_module;
|
||||
let module2 = self.resolver.current_module;
|
||||
let def_index = expansion_data[&mark.as_u32()].def_index;
|
||||
let visit_macro_invoc = &mut |id: ast::NodeId, def_index| {
|
||||
expansion_data.insert(id.as_u32(), ExpansionData {
|
||||
def_index: def_index,
|
||||
module: module.clone(),
|
||||
module2: module2,
|
||||
});
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user