]> git.lizzy.rs Git - rust.git/commitdiff
Use `Resolver::visit_expansion` only with monotonic expansions.
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Mon, 19 Sep 2016 07:27:20 +0000 (07:27 +0000)
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>
Thu, 22 Sep 2016 21:14:03 +0000 (21:14 +0000)
src/librustc_resolve/lib.rs
src/librustc_resolve/macros.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs

index 7a5f255aa9f33bb0b87cd4e174799f5056aed141..0d75685df55d09e456cf7fc0d97b88d01f69aa35 100644 (file)
@@ -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 @@ pub fn new(session: &'a Session,
         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 @@ pub fn new(session: &'a Session,
 
             macro_loader: macro_loader,
             macro_names: FnvHashSet(),
-            expansion_data: vec![macros::ExpansionData::default()],
+            expansion_data: expansion_data,
         }
     }
 
index e452a44cea5878b7fafaacd258dcbb04efcbf35a..67b7dc1a69fb0e77df6e6bf0799fbbfa2f912cf2 100644 (file)
@@ -47,7 +47,7 @@ fn next_node_id(&mut self) -> ast::NodeId {
 
     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 @@ fn add_macro(&mut self, scope: Mark, ident: ast::Ident, ext: Rc<SyntaxExtension>
             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 @@ fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec<Mark>) {
     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 @@ fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::At
         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 @@ fn resolve_invoc(&mut self, invoc: &Invocation) -> Option<Rc<SyntaxExtension>> {
             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(),
         });
     }
index 9d0d74138cd4425403893e115db96f4e3baecdf7..87337c6a26950cddb9327ee1e0b2fa444395faca 100644 (file)
@@ -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 @@ fn add_macro(&mut self, _scope: Mark, _ident: ast::Ident, _ext: Rc<SyntaxExtensi
     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)]
index db0183a8b3a2778402cc771303a5f36de8eef9b3..92c8292ae90be2caa5f306684b474e4eed3bd808 100644 (file)
@@ -165,10 +165,6 @@ fn span(&self) -> Span {
             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 @@ fn expand(&mut self, expansion: Expansion) -> Expansion {
             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 @@ fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invoc
         };
         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 @@ fn expand_attr_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) ->
 
     /// 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!(),