about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-09-16 08:50:34 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-10-07 21:54:05 +0000
commit2cf964967c48376c97fa6e2288ca26f8081f78c3 (patch)
tree6733195bb02cd1ea0b452c8c753f9ecf36bdf152 /src
parentf3c7333f51cac1e492f3d6d229149f14c160d662 (diff)
Immutable `ExpansionData`.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs6
-rw-r--r--src/librustc_resolve/lib.rs11
-rw-r--r--src/librustc_resolve/macros.rs43
3 files changed, 37 insertions, 23 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 321b814238c..79f133770b3 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -203,7 +203,7 @@ impl<'b> Resolver<'b> {
                                 let ext = macro_rules::compile(&self.session.parse_sess, &def);
                                 let shadowing =
                                     self.resolve_macro_name(Mark::root(), name, false).is_some();
-                                self.expansion_data[&Mark::root()].module.macros.borrow_mut()
+                                self.expansion_data[&Mark::root()].module.get().macros.borrow_mut()
                                     .insert(name, macros::NameBinding {
                                         ext: Rc::new(ext),
                                         expansion: expansion,
@@ -525,8 +525,8 @@ pub struct BuildReducedGraphVisitor<'a, 'b: 'a> {
 
 impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     fn visit_invoc(&mut self, id: ast::NodeId) {
-        self.resolver.expansion_data.get_mut(&Mark::from_placeholder_id(id)).unwrap().module =
-            self.resolver.current_module;
+        let mark = Mark::from_placeholder_id(id);
+        self.resolver.expansion_data[&mark].module.set(self.resolver.current_module);
     }
 }
 
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 4f41dfc8b64..a03d23a9394 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -77,6 +77,7 @@ use std::mem::replace;
 use std::rc::Rc;
 
 use resolve_imports::{ImportDirective, NameResolution};
+use macros::ExpansionData;
 
 // NB: This module needs to be declared first so diagnostics are
 // registered before they are used.
@@ -1088,7 +1089,7 @@ pub struct Resolver<'a> {
     macro_names: FnvHashSet<Name>,
 
     // Maps the `Mark` of an expansion to its containing module or block.
-    expansion_data: FnvHashMap<Mark, macros::ExpansionData<'a>>,
+    expansion_data: FnvHashMap<Mark, &'a ExpansionData<'a>>,
 }
 
 pub struct ResolverArenas<'a> {
@@ -1097,6 +1098,7 @@ pub struct ResolverArenas<'a> {
     name_bindings: arena::TypedArena<NameBinding<'a>>,
     import_directives: arena::TypedArena<ImportDirective<'a>>,
     name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
+    expansion_data: arena::TypedArena<ExpansionData<'a>>,
 }
 
 impl<'a> ResolverArenas<'a> {
@@ -1120,6 +1122,9 @@ impl<'a> ResolverArenas<'a> {
     fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
         self.name_resolutions.alloc(Default::default())
     }
+    fn alloc_expansion_data(&'a self, expansion_data: ExpansionData<'a>) -> &'a ExpansionData<'a> {
+        self.expansion_data.alloc(expansion_data)
+    }
 }
 
 impl<'a> ty::NodeIdTree for Resolver<'a> {
@@ -1206,7 +1211,8 @@ impl<'a> Resolver<'a> {
         DefCollector::new(&mut definitions).collect_root();
 
         let mut expansion_data = FnvHashMap();
-        expansion_data.insert(Mark::root(), macros::ExpansionData::root(graph_root));
+        expansion_data.insert(Mark::root(),
+                              arenas.alloc_expansion_data(ExpansionData::root(graph_root)));
 
         Resolver {
             session: session,
@@ -1277,6 +1283,7 @@ impl<'a> Resolver<'a> {
             name_bindings: arena::TypedArena::new(),
             import_directives: arena::TypedArena::new(),
             name_resolutions: arena::TypedArena::new(),
+            expansion_data: arena::TypedArena::new(),
         }
     }
 
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 3f6c69278be..ee3edbccabc 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -12,6 +12,7 @@ use {Module, Resolver};
 use build_reduced_graph::BuildReducedGraphVisitor;
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
 use rustc::hir::map::{self, DefCollector};
+use std::cell::Cell;
 use std::rc::Rc;
 use syntax::ast;
 use syntax::errors::DiagnosticBuilder;
@@ -35,7 +36,7 @@ pub struct NameBinding {
 #[derive(Clone)]
 pub struct ExpansionData<'a> {
     backtrace: SyntaxContext,
-    pub module: Module<'a>,
+    pub module: Cell<Module<'a>>,
     def_index: DefIndex,
     // True if this expansion is in a `const_integer` position, for example `[u32; m!()]`.
     // c.f. `DefCollector::visit_ast_const_integer`.
@@ -46,7 +47,7 @@ impl<'a> ExpansionData<'a> {
     pub fn root(graph_root: Module<'a>) -> Self {
         ExpansionData {
             backtrace: SyntaxContext::empty(),
-            module: graph_root,
+            module: Cell::new(graph_root),
             def_index: CRATE_DEF_INDEX,
             const_integer: false,
         }
@@ -61,18 +62,18 @@ impl<'a> base::Resolver for Resolver<'a> {
     fn get_module_scope(&mut self, id: ast::NodeId) -> Mark {
         let mark = Mark::fresh();
         let module = self.module_map[&id];
-        self.expansion_data.insert(mark, ExpansionData {
+        self.expansion_data.insert(mark, self.arenas.alloc_expansion_data(ExpansionData {
             backtrace: SyntaxContext::empty(),
-            module: module,
+            module: Cell::new(module),
             def_index: module.def_id().unwrap().index,
             const_integer: false,
-        });
+        }));
         mark
     }
 
     fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
         self.collect_def_ids(mark, expansion);
-        self.current_module = self.expansion_data[&mark].module;
+        self.current_module = self.expansion_data[&mark].module.get();
         expansion.visit_with(&mut BuildReducedGraphVisitor { resolver: self, expansion: mark });
     }
 
@@ -81,13 +82,14 @@ impl<'a> base::Resolver for Resolver<'a> {
             self.session.span_err(def.span, "user-defined macros may not be named `macro_rules`");
         }
         if def.use_locally {
-            let ExpansionData { mut module, backtrace, .. } = self.expansion_data[&scope];
+            let expansion_data = self.expansion_data[&scope];
+            let mut module = expansion_data.module.get();
             while module.macros_escape {
                 module = module.parent.unwrap();
             }
             let binding = NameBinding {
                 ext: Rc::new(macro_rules::compile(&self.session.parse_sess, &def)),
-                expansion: backtrace.data().prev_ctxt.data().outer_mark,
+                expansion: expansion_data.backtrace.data().prev_ctxt.data().outer_mark,
                 shadowing: self.resolve_macro_name(scope, def.ident.name, false).is_some(),
                 span: def.span,
             };
@@ -119,7 +121,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[&Mark::root()].module.macros.borrow().get(&name) {
+            match self.expansion_data[&Mark::root()].module.get().macros.borrow().get(&name) {
                 Some(binding) => match *binding.ext {
                     MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
                         return Some(attrs.remove(i))
@@ -164,10 +166,11 @@ impl<'a> base::Resolver for Resolver<'a> {
 impl<'a> Resolver<'a> {
     pub fn resolve_macro_name(&mut self, scope: Mark, name: ast::Name, record_used: bool)
                               -> Option<Rc<SyntaxExtension>> {
-        let ExpansionData { mut module, backtrace, .. } = self.expansion_data[&scope];
+        let expansion_data = self.expansion_data[&scope];
+        let mut module = expansion_data.module.get();
         loop {
             if let Some(binding) = module.macros.borrow().get(&name) {
-                let mut backtrace = backtrace.data();
+                let mut backtrace = expansion_data.backtrace.data();
                 while binding.expansion != backtrace.outer_mark {
                     if backtrace.outer_mark != Mark::root() {
                         backtrace = backtrace.prev_ctxt.data();
@@ -205,14 +208,18 @@ impl<'a> Resolver<'a> {
     }
 
     fn collect_def_ids(&mut self, mark: Mark, expansion: &Expansion) {
-        let expansion_data = &mut self.expansion_data;
-        let ExpansionData { backtrace, def_index, const_integer, module } = expansion_data[&mark];
+        let Resolver { ref mut expansion_data, arenas, graph_root, .. } = *self;
+        let ExpansionData { def_index, const_integer, backtrace, .. } =
+            expansion_data[&mark].clone();
+
         let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
-            expansion_data.entry(invoc.mark).or_insert(ExpansionData {
-                backtrace: backtrace.apply_mark(invoc.mark),
-                def_index: invoc.def_index,
-                const_integer: invoc.const_integer,
-                module: module,
+            expansion_data.entry(invoc.mark).or_insert_with(|| {
+                arenas.alloc_expansion_data(ExpansionData {
+                    backtrace: backtrace.apply_mark(invoc.mark),
+                    def_index: invoc.def_index,
+                    const_integer: invoc.const_integer,
+                    module: Cell::new(graph_root),
+                })
             });
         };