Auto merge of #36573 - jseyfried:groundwork, r=nrc

resolve: groundwork for building the module graph during expansion

r? @nrc
This commit is contained in:
bors 2016-09-22 19:54:56 -07:00 committed by GitHub
commit 533c04dbb3
9 changed files with 172 additions and 186 deletions

View file

@ -30,19 +30,12 @@ pub struct DefCollector<'ast> {
}
impl<'ast> DefCollector<'ast> {
pub fn root(definitions: &'ast mut Definitions) -> DefCollector<'ast> {
let mut collector = DefCollector {
pub fn new(definitions: &'ast mut Definitions) -> DefCollector<'ast> {
DefCollector {
hir_crate: None,
definitions: definitions,
parent_def: None,
};
let root = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot);
assert_eq!(root, CRATE_DEF_INDEX);
collector.parent_def = Some(root);
collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc);
collector
}
}
pub fn extend(parent_node: NodeId,
@ -50,11 +43,7 @@ impl<'ast> DefCollector<'ast> {
parent_def_id: DefId,
definitions: &'ast mut Definitions)
-> DefCollector<'ast> {
let mut collector = DefCollector {
hir_crate: None,
parent_def: None,
definitions: definitions,
};
let mut collector = DefCollector::new(definitions);
assert_eq!(parent_def_path.krate, parent_def_id.krate);
let root_path = Box::new(InlinedRootPath {
@ -68,17 +57,21 @@ impl<'ast> DefCollector<'ast> {
collector
}
pub fn collect_root(&mut self) {
let root = self.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot);
assert_eq!(root, CRATE_DEF_INDEX);
self.parent_def = Some(root);
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) {
self.hir_crate = Some(krate);
ii.visit(self);
}
fn parent_def(&self) -> Option<DefIndex> {
self.parent_def
}
fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex {
let parent_def = self.parent_def();
let parent_def = self.parent_def;
debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
self.definitions.create_def_with_parent(parent_def, node_id, data)
}

View file

@ -225,7 +225,8 @@ impl Definitions {
}
pub fn collect(&mut self, krate: &ast::Crate) {
let mut def_collector = DefCollector::root(self);
let mut def_collector = DefCollector::new(self);
def_collector.collect_root();
visit::walk_crate(&mut def_collector, krate);
}

View file

@ -643,7 +643,8 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
macro_import::MacroLoader::new(sess, &cstore, crate_name, krate.config.clone());
let resolver_arenas = Resolver::arenas();
let mut resolver = Resolver::new(sess, make_glob_map, &mut macro_loader, &resolver_arenas);
let mut resolver =
Resolver::new(sess, &krate, make_glob_map, &mut macro_loader, &resolver_arenas);
syntax_ext::register_builtins(&mut resolver, sess.features.borrow().quote);
krate = time(time_passes, "expansion", || {

View file

@ -14,10 +14,9 @@
//! any imports resolved.
use resolve_imports::ImportDirectiveSubclass::{self, GlobImport};
use Module;
use {Module, ModuleS, ModuleKind};
use Namespace::{self, TypeNS, ValueNS};
use {NameBinding, NameBindingKind, ToNameBinding};
use ParentLink::{ModuleParentLink, BlockParentLink};
use Resolver;
use {resolve_error, resolve_struct_error, ResolutionError};
@ -34,7 +33,7 @@ use syntax::parse::token;
use syntax::ast::{Block, Crate};
use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind};
use syntax::ast::{Mutability, StmtKind, TraitItemKind};
use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::parse::token::keywords;
use syntax::visit::{self, Visitor};
@ -56,8 +55,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) {
let no_implicit_prelude = attr::contains_name(&krate.attrs, "no_implicit_prelude");
self.graph_root.no_implicit_prelude.set(no_implicit_prelude);
visit::walk_crate(&mut BuildReducedGraphVisitor { resolver: self }, krate);
}
@ -196,9 +193,11 @@ impl<'b> Resolver<'b> {
krate: crate_id,
index: CRATE_DEF_INDEX,
};
let parent_link = ModuleParentLink(parent, name);
let def = Def::Mod(def_id);
let module = self.new_extern_crate_module(parent_link, def, item.id);
let module = self.arenas.alloc_module(ModuleS {
extern_crate_id: Some(item.id),
populated: Cell::new(false),
..ModuleS::new(Some(parent), ModuleKind::Def(Def::Mod(def_id), name))
});
self.define(parent, name, TypeNS, (module, sp, vis));
self.populate_module_if_necessary(module);
@ -206,12 +205,13 @@ impl<'b> Resolver<'b> {
}
ItemKind::Mod(..) => {
let parent_link = ModuleParentLink(parent, name);
let def = Def::Mod(self.definitions.local_def_id(item.id));
let module = self.new_module(parent_link, Some(def), Some(item.id));
module.no_implicit_prelude.set({
parent.no_implicit_prelude.get() ||
let module = self.arenas.alloc_module(ModuleS {
no_implicit_prelude: parent.no_implicit_prelude || {
attr::contains_name(&item.attrs, "no_implicit_prelude")
},
normal_ancestor_id: Some(item.id),
..ModuleS::new(Some(parent), ModuleKind::Def(def, name))
});
self.define(parent, name, TypeNS, (module, sp, vis));
self.module_map.insert(item.id, module);
@ -244,9 +244,8 @@ impl<'b> Resolver<'b> {
}
ItemKind::Enum(ref enum_definition, _) => {
let parent_link = ModuleParentLink(parent, name);
let def = Def::Enum(self.definitions.local_def_id(item.id));
let module = self.new_module(parent_link, Some(def), parent.normal_ancestor_id);
let module = self.new_module(parent, ModuleKind::Def(def, name), true);
self.define(parent, name, TypeNS, (module, sp, vis));
for variant in &(*enum_definition).variants {
@ -293,40 +292,17 @@ impl<'b> Resolver<'b> {
ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => {}
ItemKind::Trait(.., ref items) => {
ItemKind::Trait(..) => {
let def_id = self.definitions.local_def_id(item.id);
// Add all the items within to a new module.
let parent_link = ModuleParentLink(parent, name);
let def = Def::Trait(def_id);
let module_parent =
self.new_module(parent_link, Some(def), parent.normal_ancestor_id);
self.define(parent, name, TypeNS, (module_parent, sp, vis));
// Add the names of all the items to the trait info.
for item in items {
let item_def_id = self.definitions.local_def_id(item.id);
let mut is_static_method = false;
let (def, ns) = match item.node {
TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
TraitItemKind::Method(ref sig, _) => {
is_static_method = !sig.decl.has_self();
(Def::Method(item_def_id), ValueNS)
}
TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
};
self.define(module_parent, item.ident.name, ns, (def, item.span, vis));
self.trait_item_map.insert((item.ident.name, def_id), is_static_method);
}
let module =
self.new_module(parent, ModuleKind::Def(Def::Trait(def_id), name), true);
self.define(parent, name, TypeNS, (module, sp, vis));
self.current_module = module;
}
ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
}
visit::walk_item(&mut BuildReducedGraphVisitor { resolver: self }, item);
self.current_module = parent;
}
// Constructs the reduced graph for one variant. Variants exist in the
@ -375,14 +351,10 @@ impl<'b> Resolver<'b> {
{}",
block_id);
let parent_link = BlockParentLink(parent, block_id);
let new_module = self.new_module(parent_link, None, parent.normal_ancestor_id);
let new_module = self.new_module(parent, ModuleKind::Block(block_id), true);
self.module_map.insert(block_id, new_module);
self.current_module = new_module; // Descend into the block.
}
visit::walk_block(&mut BuildReducedGraphVisitor { resolver: self }, block);
self.current_module = parent;
}
/// Builds the reduced graph for a single item in an external crate.
@ -407,8 +379,7 @@ impl<'b> Resolver<'b> {
Def::Mod(_) | Def::Enum(..) => {
debug!("(building reduced graph for external crate) building module {} {:?}",
name, vis);
let parent_link = ModuleParentLink(parent, name);
let module = self.new_module(parent_link, Some(def), None);
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::Variant(variant_id) => {
@ -451,8 +422,7 @@ impl<'b> Resolver<'b> {
self.trait_item_map.insert((trait_item_name, def_id), false);
}
let parent_link = ModuleParentLink(parent, name);
let module = self.new_module(parent_link, Some(def), None);
let module = self.new_module(parent, ModuleKind::Def(def, name), false);
let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis));
}
Def::TyAlias(..) | Def::AssociatedTy(..) => {
@ -512,7 +482,10 @@ struct BuildReducedGraphVisitor<'a, 'b: 'a> {
impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
fn visit_item(&mut self, item: &Item) {
let parent = self.resolver.current_module;
self.resolver.build_reduced_graph_for_item(item);
visit::walk_item(self, item);
self.resolver.current_module = parent;
}
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
@ -520,6 +493,36 @@ impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
}
fn visit_block(&mut self, block: &Block) {
let parent = self.resolver.current_module;
self.resolver.build_reduced_graph_for_block(block);
visit::walk_block(self, block);
self.resolver.current_module = parent;
}
fn visit_trait_item(&mut self, item: &TraitItem) {
let parent = self.resolver.current_module;
let def_id = parent.def_id().unwrap();
// Add the item to the trait info.
let item_def_id = self.resolver.definitions.local_def_id(item.id);
let mut is_static_method = false;
let (def, ns) = match item.node {
TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS),
TraitItemKind::Method(ref sig, _) => {
is_static_method = !sig.decl.has_self();
(Def::Method(item_def_id), ValueNS)
}
TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS),
TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"),
};
self.resolver.trait_item_map.insert((item.ident.name, def_id), is_static_method);
let vis = ty::Visibility::Public;
self.resolver.define(parent, item.ident.name, ns, (def, item.span, vis));
self.resolver.current_module = parent.parent.unwrap(); // nearest normal ancestor
visit::walk_trait_item(self, item);
self.resolver.current_module = parent;
}
}

View file

@ -41,7 +41,6 @@ use self::TypeParameters::*;
use self::RibKind::*;
use self::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
use self::ParentLink::*;
use rustc::hir::map::Definitions;
use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr};
@ -61,6 +60,7 @@ use syntax::parse::token::{self, keywords};
use syntax::util::lev_distance::find_best_match_for_name;
use syntax::visit::{self, FnKind, Visitor};
use syntax::attr;
use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind};
use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics};
use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind};
@ -753,18 +753,15 @@ impl<'a> LexicalScopeBinding<'a> {
}
}
/// The link from a module up to its nearest parent node.
#[derive(Clone,Debug)]
enum ParentLink<'a> {
NoParentLink,
ModuleParentLink(Module<'a>, Name),
BlockParentLink(Module<'a>, NodeId),
enum ModuleKind {
Block(NodeId),
Def(Def, Name),
}
/// One node in the tree of modules.
pub struct ModuleS<'a> {
parent_link: ParentLink<'a>,
def: Option<Def>,
parent: Option<Module<'a>>,
kind: ModuleKind,
// The node id of the closest normal module (`mod`) ancestor (including this module).
normal_ancestor_id: Option<NodeId>,
@ -775,7 +772,7 @@ pub struct ModuleS<'a> {
resolutions: RefCell<FnvHashMap<(Name, Namespace), &'a RefCell<NameResolution<'a>>>>,
no_implicit_prelude: Cell<bool>,
no_implicit_prelude: bool,
glob_importers: RefCell<Vec<&'a ImportDirective<'a>>>,
globs: RefCell<Vec<&'a ImportDirective<'a>>>,
@ -792,19 +789,18 @@ pub struct ModuleS<'a> {
pub type Module<'a> = &'a ModuleS<'a>;
impl<'a> ModuleS<'a> {
fn new(parent_link: ParentLink<'a>, def: Option<Def>, normal_ancestor_id: Option<NodeId>)
-> Self {
fn new(parent: Option<Module<'a>>, kind: ModuleKind) -> Self {
ModuleS {
parent_link: parent_link,
def: def,
normal_ancestor_id: normal_ancestor_id,
parent: parent,
kind: kind,
normal_ancestor_id: None,
extern_crate_id: None,
resolutions: RefCell::new(FnvHashMap()),
no_implicit_prelude: Cell::new(false),
no_implicit_prelude: false,
glob_importers: RefCell::new(Vec::new()),
globs: RefCell::new((Vec::new())),
traits: RefCell::new(None),
populated: Cell::new(normal_ancestor_id.is_some()),
populated: Cell::new(true),
}
}
@ -814,36 +810,36 @@ impl<'a> ModuleS<'a> {
}
}
fn def(&self) -> Option<Def> {
match self.kind {
ModuleKind::Def(def, _) => Some(def),
_ => None,
}
}
fn def_id(&self) -> Option<DefId> {
self.def.as_ref().map(Def::def_id)
self.def().as_ref().map(Def::def_id)
}
// `self` resolves to the first module ancestor that `is_normal`.
fn is_normal(&self) -> bool {
match self.def {
Some(Def::Mod(_)) => true,
match self.kind {
ModuleKind::Def(Def::Mod(_), _) => true,
_ => false,
}
}
fn is_trait(&self) -> bool {
match self.def {
Some(Def::Trait(_)) => true,
match self.kind {
ModuleKind::Def(Def::Trait(_), _) => true,
_ => false,
}
}
fn parent(&self) -> Option<&'a Self> {
match self.parent_link {
ModuleParentLink(parent, _) | BlockParentLink(parent, _) => Some(parent),
NoParentLink => None,
}
}
}
impl<'a> fmt::Debug for ModuleS<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.def)
write!(f, "{:?}", self.def())
}
}
@ -903,7 +899,7 @@ impl<'a> NameBinding<'a> {
fn def(&self) -> Def {
match self.kind {
NameBindingKind::Def(def) => def,
NameBindingKind::Module(module) => module.def.unwrap(),
NameBindingKind::Module(module) => module.def().unwrap(),
NameBindingKind::Import { binding, .. } => binding.def(),
NameBindingKind::Ambiguity { .. } => Def::Err,
}
@ -1074,7 +1070,7 @@ pub struct Resolver<'a> {
macro_names: FnvHashSet<Name>,
// Maps the `Mark` of an expansion to its containing module or block.
expansion_data: Vec<macros::ExpansionData>,
expansion_data: FnvHashMap<u32, macros::ExpansionData>,
}
pub struct ResolverArenas<'a> {
@ -1111,7 +1107,7 @@ impl<'a> ResolverArenas<'a> {
impl<'a> ty::NodeIdTree for Resolver<'a> {
fn is_descendant_of(&self, mut node: NodeId, ancestor: NodeId) -> bool {
while node != ancestor {
node = match self.module_map[&node].parent() {
node = match self.module_map[&node].parent {
Some(parent) => parent.normal_ancestor_id.unwrap(),
None => return false,
}
@ -1174,17 +1170,23 @@ impl Named for hir::PathSegment {
impl<'a> Resolver<'a> {
pub fn new(session: &'a Session,
krate: &Crate,
make_glob_map: MakeGlobMap,
macro_loader: &'a mut MacroLoader,
arenas: &'a ResolverArenas<'a>)
-> Resolver<'a> {
let root_def_id = DefId::local(CRATE_DEF_INDEX);
let graph_root =
ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), Some(CRATE_NODE_ID));
let graph_root = arenas.alloc_module(graph_root);
let root_def = Def::Mod(DefId::local(CRATE_DEF_INDEX));
let graph_root = arenas.alloc_module(ModuleS {
normal_ancestor_id: Some(CRATE_NODE_ID),
no_implicit_prelude: attr::contains_name(&krate.attrs, "no_implicit_prelude"),
..ModuleS::new(None, ModuleKind::Def(root_def, keywords::Invalid.name()))
});
let mut module_map = NodeMap();
module_map.insert(CRATE_NODE_ID, graph_root);
let mut expansion_data = FnvHashMap();
expansion_data.insert(0, macros::ExpansionData::default()); // Crate root expansion
Resolver {
session: session,
@ -1240,7 +1242,7 @@ impl<'a> Resolver<'a> {
macro_loader: macro_loader,
macro_names: FnvHashSet(),
expansion_data: vec![macros::ExpansionData::default()],
expansion_data: expansion_data,
}
}
@ -1263,20 +1265,12 @@ impl<'a> Resolver<'a> {
self.report_errors();
}
fn new_module(&self,
parent_link: ParentLink<'a>,
def: Option<Def>,
normal_ancestor_id: Option<NodeId>)
-> Module<'a> {
self.arenas.alloc_module(ModuleS::new(parent_link, def, normal_ancestor_id))
}
fn new_extern_crate_module(&self, parent_link: ParentLink<'a>, def: Def, local_node_id: NodeId)
-> Module<'a> {
let mut module = ModuleS::new(parent_link, Some(def), Some(local_node_id));
module.extern_crate_id = Some(local_node_id);
module.populated.set(false);
self.arenas.modules.alloc(module)
fn new_module(&self, parent: Module<'a>, kind: ModuleKind, local: bool) -> Module<'a> {
self.arenas.alloc_module(ModuleS {
normal_ancestor_id: if local { self.current_module.normal_ancestor_id } else { None },
populated: Cell::new(local),
..ModuleS::new(Some(parent), kind)
})
}
fn get_ribs<'b>(&'b mut self, ns: Namespace) -> &'b mut Vec<Rib<'a>> {
@ -1336,11 +1330,10 @@ impl<'a> Resolver<'a> {
-> Option<Module<'a>> {
match this.resolve_name_in_module(module, needle, TypeNS, false, None) {
Success(binding) if binding.is_extern_crate() => Some(module),
_ => match module.parent_link {
ModuleParentLink(ref parent, _) => {
search_parent_externals(this, needle, parent)
}
_ => None,
_ => if let (&ModuleKind::Def(..), Some(parent)) = (&module.kind, module.parent) {
search_parent_externals(this, needle, parent)
} else {
None
},
}
}
@ -1516,15 +1509,13 @@ impl<'a> Resolver<'a> {
return Some(LexicalScopeBinding::Item(binding));
}
// We can only see through anonymous modules
if module.def.is_some() {
return match self.prelude {
Some(prelude) if !module.no_implicit_prelude.get() => {
self.resolve_name_in_module(prelude, name, ns, false, None).success()
.map(LexicalScopeBinding::Item)
}
_ => None,
};
if let ModuleKind::Block(..) = module.kind { // We can see through blocks
} else if !module.no_implicit_prelude {
return self.prelude.and_then(|prelude| {
self.resolve_name_in_module(prelude, name, ns, false, None).success()
}).map(LexicalScopeBinding::Item)
} else {
return None;
}
}
@ -1561,7 +1552,7 @@ impl<'a> Resolver<'a> {
while i < module_path.len() && "super" == module_path[i].as_str() {
debug!("(resolving module prefix) resolving `super` at {}",
module_to_string(&containing_module));
if let Some(parent) = containing_module.parent() {
if let Some(parent) = containing_module.parent {
containing_module = self.module_map[&parent.normal_ancestor_id.unwrap()];
i += 1;
} else {
@ -2954,7 +2945,7 @@ impl<'a> Resolver<'a> {
UseLexicalScope,
Some(expr.span)) {
Success(e) => {
if let Some(def_type) = e.def {
if let Some(def_type) = e.def() {
def = def_type;
}
context = UnresolvedNameContext::PathIsMod(parent);
@ -3163,16 +3154,13 @@ impl<'a> Resolver<'a> {
};
search_in_module(self, search_module);
match search_module.parent_link {
NoParentLink | ModuleParentLink(..) => {
if !search_module.no_implicit_prelude.get() {
self.prelude.map(|prelude| search_in_module(self, prelude));
}
break;
}
BlockParentLink(parent_module, _) => {
search_module = parent_module;
if let ModuleKind::Block(..) = search_module.kind {
search_module = search_module.parent.unwrap();
} else {
if !search_module.no_implicit_prelude {
self.prelude.map(|prelude| search_in_module(self, prelude));
}
break;
}
}
@ -3240,9 +3228,9 @@ impl<'a> Resolver<'a> {
// collect submodules to explore
if let Ok(module) = name_binding.module() {
// form the path
let path_segments = match module.parent_link {
NoParentLink => path_segments.clone(),
ModuleParentLink(_, name) => {
let path_segments = match module.kind {
_ if module.parent.is_none() => path_segments.clone(),
ModuleKind::Def(_, name) => {
let mut paths = path_segments.clone();
let ident = ast::Ident::with_empty_ctxt(name);
let params = PathParameters::none();
@ -3259,7 +3247,7 @@ impl<'a> Resolver<'a> {
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
// add the module to the lookup
let is_extern = in_module_is_extern || name_binding.is_extern_crate();
if !worklist.iter().any(|&(m, ..)| m.def == module.def) {
if !worklist.iter().any(|&(m, ..)| m.def() == module.def()) {
worklist.push((module, path_segments, is_extern));
}
}
@ -3294,7 +3282,7 @@ impl<'a> Resolver<'a> {
let mut path_resolution = err_path_resolution();
let vis = match self.resolve_module_path(&segments, DontUseLexicalScope, Some(path.span)) {
Success(module) => {
path_resolution = PathResolution::new(module.def.unwrap());
path_resolution = PathResolution::new(module.def().unwrap());
ty::Visibility::Restricted(module.normal_ancestor_id.unwrap())
}
Indeterminate => unreachable!(),
@ -3360,10 +3348,10 @@ impl<'a> Resolver<'a> {
return self.report_conflict(parent, name, ns, old_binding, binding);
}
let container = match parent.def {
Some(Def::Mod(_)) => "module",
Some(Def::Trait(_)) => "trait",
None => "block",
let container = match parent.kind {
ModuleKind::Def(Def::Mod(_), _) => "module",
ModuleKind::Def(Def::Trait(_), _) => "trait",
ModuleKind::Block(..) => "block",
_ => "enum",
};
@ -3510,17 +3498,15 @@ fn module_to_string(module: Module) -> String {
let mut names = Vec::new();
fn collect_mod(names: &mut Vec<ast::Name>, module: Module) {
match module.parent_link {
NoParentLink => {}
ModuleParentLink(ref module, name) => {
if let ModuleKind::Def(_, name) = module.kind {
if let Some(parent) = module.parent {
names.push(name);
collect_mod(names, module);
}
BlockParentLink(ref module, _) => {
// danger, shouldn't be ident?
names.push(token::intern("<opaque>"));
collect_mod(names, module);
collect_mod(names, parent);
}
} else {
// danger, shouldn't be ident?
names.push(token::intern("<opaque>"));
collect_mod(names, module);
}
}
collect_mod(&mut names, module);

View file

@ -47,7 +47,7 @@ impl<'a> base::Resolver for Resolver<'a> {
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
expansion.visit_with(&mut ExpansionVisitor {
current_module: self.expansion_data[mark.as_u32() as usize].module.clone(),
current_module: self.expansion_data[&mark.as_u32()].module.clone(),
resolver: self,
});
}
@ -57,7 +57,7 @@ impl<'a> base::Resolver for Resolver<'a> {
self.macro_names.insert(ident.name);
}
let mut module = self.expansion_data[scope.as_u32() as usize].module.clone();
let mut module = self.expansion_data[&scope.as_u32()].module.clone();
while module.macros_escape {
module = module.parent.clone().unwrap();
}
@ -71,7 +71,7 @@ impl<'a> base::Resolver for Resolver<'a> {
fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
for i in 0..attrs.len() {
let name = intern(&attrs[i].name());
match self.expansion_data[0].module.macros.borrow().get(&name) {
match self.expansion_data[&0].module.macros.borrow().get(&name) {
Some(ext) => match **ext {
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
return Some(attrs.remove(i))
@ -84,7 +84,7 @@ impl<'a> base::Resolver for Resolver<'a> {
None
}
fn resolve_invoc(&mut self, invoc: &Invocation) -> Option<Rc<SyntaxExtension>> {
fn resolve_invoc(&mut self, scope: Mark, invoc: &Invocation) -> Option<Rc<SyntaxExtension>> {
let (name, span) = match invoc.kind {
InvocationKind::Bang { ref mac, .. } => {
let path = &mac.node.path;
@ -99,7 +99,7 @@ impl<'a> base::Resolver for Resolver<'a> {
InvocationKind::Attr { ref attr, .. } => (intern(&*attr.name()), attr.span),
};
let mut module = self.expansion_data[invoc.mark().as_u32() as usize].module.clone();
let mut module = self.expansion_data[&scope.as_u32()].module.clone();
loop {
if let Some(ext) = module.macros.borrow().get(&name) {
return Some(ext.clone());
@ -137,8 +137,7 @@ struct ExpansionVisitor<'b, 'a: 'b> {
impl<'a, 'b> ExpansionVisitor<'a, 'b> {
fn visit_invoc(&mut self, id: ast::NodeId) {
assert_eq!(id.as_u32(), self.resolver.expansion_data.len() as u32);
self.resolver.expansion_data.push(ExpansionData {
self.resolver.expansion_data.insert(id.as_u32(), ExpansionData {
module: self.current_module.clone(),
});
}

View file

@ -733,7 +733,7 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
let module = directive.imported_module.get().unwrap();
self.populate_module_if_necessary(module);
if let Some(Def::Trait(_)) = module.def {
if let Some(Def::Trait(_)) = module.def() {
self.session.span_err(directive.span, "items in traits are not importable.");
return;
} else if module.def_id() == directive.parent.def_id() {

View file

@ -667,7 +667,7 @@ pub trait Resolver {
fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec<Mark>);
fn find_attr_invoc(&mut self, attrs: &mut Vec<Attribute>) -> Option<Attribute>;
fn resolve_invoc(&mut self, invoc: &Invocation) -> Option<Rc<SyntaxExtension>>;
fn resolve_invoc(&mut self, scope: Mark, invoc: &Invocation) -> Option<Rc<SyntaxExtension>>;
}
pub enum LoadedMacro {
@ -688,7 +688,9 @@ impl Resolver for DummyResolver {
fn add_expansions_at_stmt(&mut self, _id: ast::NodeId, _macros: Vec<Mark>) {}
fn find_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>) -> Option<Attribute> { None }
fn resolve_invoc(&mut self, _invoc: &Invocation) -> Option<Rc<SyntaxExtension>> { None }
fn resolve_invoc(&mut self, _scope: Mark, _invoc: &Invocation) -> Option<Rc<SyntaxExtension>> {
None
}
}
#[derive(Clone)]

View file

@ -168,10 +168,6 @@ impl Invocation {
InvocationKind::Attr { ref attr, .. } => attr.span,
}
}
pub fn mark(&self) -> Mark {
self.expansion_data.mark
}
}
pub struct MacroExpander<'a, 'b:'a> {
@ -229,7 +225,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
let ExpansionData { depth, mark, .. } = invoc.expansion_data;
self.cx.current_expansion = invoc.expansion_data.clone();
let expansion = match self.cx.resolver.resolve_invoc(&invoc) {
let scope = if self.monotonic { mark } else { orig_expansion_data.mark };
self.cx.current_expansion.mark = scope;
let expansion = match self.cx.resolver.resolve_invoc(scope, &invoc) {
Some(ext) => self.expand_invoc(invoc, ext),
None => invoc.expansion_kind.dummy(invoc.span()),
};
@ -277,8 +275,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
};
self.cx.cfg = crate_config;
let mark = self.cx.current_expansion.mark;
self.cx.resolver.visit_expansion(mark, &result.0);
if self.monotonic {
let mark = self.cx.current_expansion.mark;
self.cx.resolver.visit_expansion(mark, &result.0);
}
result
}
@ -338,7 +339,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
/// Expand a macro invocation. Returns the result of expansion.
fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> Expansion {
let (mark, kind) = (invoc.mark(), invoc.expansion_kind);
let (mark, kind) = (invoc.expansion_data.mark, invoc.expansion_kind);
let (attrs, mac, ident, span) = match invoc.kind {
InvocationKind::Bang { attrs, mac, ident, span } => (attrs, mac, ident, span),
_ => unreachable!(),