diff options
| -rw-r--r-- | src/librustc_resolve/lib.rs | 7 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/base.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 17 |
4 files changed, 24 insertions, 19 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 7a5f255aa9f..0d75685df55 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1070,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> { @@ -1184,6 +1184,9 @@ impl<'a> Resolver<'a> { 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, @@ -1239,7 +1242,7 @@ impl<'a> Resolver<'a> { macro_loader: macro_loader, macro_names: FnvHashSet(), - expansion_data: vec![macros::ExpansionData::default()], + expansion_data: expansion_data, } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e452a44cea5..67b7dc1a69f 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<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(..) => 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<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; @@ -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/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 9d0d74138cd..87337c6a269 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<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 { @@ -491,7 +491,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)] diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index db0183a8b3a..92c8292ae90 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<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!(), |
