diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index ea1f8aac7a55a..b0a717e18f98d 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -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 { - 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) } diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index f404f60cc9cef..5cfb71f4fc877 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -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); } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 55892801247b5..18ce35237afcb 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -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", || { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c9591c31831a8..3075e394869a5 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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; } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 016b621eabd4c..0d75685df55d0 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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, + parent: Option>, + kind: ModuleKind, // The node id of the closest normal module (`mod`) ancestor (including this module). normal_ancestor_id: Option, @@ -775,7 +772,7 @@ pub struct ModuleS<'a> { resolutions: RefCell>>>, - no_implicit_prelude: Cell, + no_implicit_prelude: bool, glob_importers: RefCell>>, globs: RefCell>>, @@ -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, normal_ancestor_id: Option) - -> Self { + fn new(parent: Option>, 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 { + match self.kind { + ModuleKind::Def(def, _) => Some(def), + _ => None, + } + } + fn def_id(&self) -> Option { - 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, // Maps the `Mark` of an expansion to its containing module or block. - expansion_data: Vec, + expansion_data: FnvHashMap, } 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, - normal_ancestor_id: Option) - -> 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> { @@ -1336,11 +1330,10 @@ impl<'a> Resolver<'a> { -> Option> { 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, 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("")); - collect_mod(names, module); + collect_mod(names, parent); } + } else { + // danger, shouldn't be ident? + names.push(token::intern("")); + collect_mod(names, module); } } collect_mod(&mut names, module); diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e452a44cea587..67b7dc1a69fb0 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -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) -> Option { 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(..) => return Some(attrs.remove(i)), _ => {} @@ -82,7 +82,7 @@ impl<'a> base::Resolver for Resolver<'a> { None } - fn resolve_invoc(&mut self, invoc: &Invocation) -> Option> { + fn resolve_invoc(&mut self, scope: Mark, invoc: &Invocation) -> Option> { let (name, span) = match invoc.kind { InvocationKind::Bang { ref mac, .. } => { let path = &mac.node.path; @@ -97,7 +97,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()); @@ -135,8 +135,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(), }); } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 29add1f9b9d49..ba45b773c09f3 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -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() { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9d0d74138cd44..87337c6a26950 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -470,7 +470,7 @@ pub trait Resolver { fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec); fn find_attr_invoc(&mut self, attrs: &mut Vec) -> Option; - fn resolve_invoc(&mut self, invoc: &Invocation) -> Option>; + fn resolve_invoc(&mut self, scope: Mark, invoc: &Invocation) -> Option>; } pub enum LoadedMacro { @@ -491,7 +491,9 @@ impl Resolver for DummyResolver { fn add_expansions_at_stmt(&mut self, _id: ast::NodeId, _macros: Vec) {} fn find_attr_invoc(&mut self, _attrs: &mut Vec) -> Option { None } - fn resolve_invoc(&mut self, _invoc: &Invocation) -> Option> { None } + fn resolve_invoc(&mut self, _scope: Mark, _invoc: &Invocation) -> Option> { + None + } } #[derive(Clone)] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index db0183a8b3a27..92c8292ae90be 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -165,10 +165,6 @@ impl Invocation { InvocationKind::Attr { ref attr, .. } => attr.span, } } - - pub fn mark(&self) -> Mark { - self.expansion_data.mark - } } pub struct MacroExpander<'a, 'b:'a> { @@ -219,7 +215,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()), }; @@ -267,8 +265,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 } @@ -314,7 +315,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) -> 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!(),