From 2cf964967c48376c97fa6e2288ca26f8081f78c3 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 16 Sep 2016 08:50:34 +0000 Subject: [PATCH] Immutable `ExpansionData`. --- src/librustc_resolve/build_reduced_graph.rs | 6 +-- src/librustc_resolve/lib.rs | 11 +++++- src/librustc_resolve/macros.rs | 43 ++++++++++++--------- 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, // Maps the `Mark` of an expansion to its containing module or block. - expansion_data: FnvHashMap>, + expansion_data: FnvHashMap>, } pub struct ResolverArenas<'a> { @@ -1097,6 +1098,7 @@ pub struct ResolverArenas<'a> { name_bindings: arena::TypedArena>, import_directives: arena::TypedArena>, name_resolutions: arena::TypedArena>>, + expansion_data: arena::TypedArena>, } impl<'a> ResolverArenas<'a> { @@ -1120,6 +1122,9 @@ impl<'a> ResolverArenas<'a> { fn alloc_name_resolution(&'a self) -> &'a RefCell> { 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>, 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) -> Option { 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> { - 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), + }) }); };