Immutable ExpansionData
.
This commit is contained in:
parent
f3c7333f51
commit
2cf964967c
3 changed files with 37 additions and 23 deletions
|
@ -203,7 +203,7 @@ impl<'b> Resolver<'b> {
|
||||||
let ext = macro_rules::compile(&self.session.parse_sess, &def);
|
let ext = macro_rules::compile(&self.session.parse_sess, &def);
|
||||||
let shadowing =
|
let shadowing =
|
||||||
self.resolve_macro_name(Mark::root(), name, false).is_some();
|
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 {
|
.insert(name, macros::NameBinding {
|
||||||
ext: Rc::new(ext),
|
ext: Rc::new(ext),
|
||||||
expansion: expansion,
|
expansion: expansion,
|
||||||
|
@ -525,8 +525,8 @@ pub struct BuildReducedGraphVisitor<'a, 'b: 'a> {
|
||||||
|
|
||||||
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
fn visit_invoc(&mut self, id: ast::NodeId) {
|
fn visit_invoc(&mut self, id: ast::NodeId) {
|
||||||
self.resolver.expansion_data.get_mut(&Mark::from_placeholder_id(id)).unwrap().module =
|
let mark = Mark::from_placeholder_id(id);
|
||||||
self.resolver.current_module;
|
self.resolver.expansion_data[&mark].module.set(self.resolver.current_module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,7 @@ use std::mem::replace;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use resolve_imports::{ImportDirective, NameResolution};
|
use resolve_imports::{ImportDirective, NameResolution};
|
||||||
|
use macros::ExpansionData;
|
||||||
|
|
||||||
// NB: This module needs to be declared first so diagnostics are
|
// NB: This module needs to be declared first so diagnostics are
|
||||||
// registered before they are used.
|
// registered before they are used.
|
||||||
|
@ -1088,7 +1089,7 @@ pub struct Resolver<'a> {
|
||||||
macro_names: FnvHashSet<Name>,
|
macro_names: FnvHashSet<Name>,
|
||||||
|
|
||||||
// Maps the `Mark` of an expansion to its containing module or block.
|
// 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> {
|
pub struct ResolverArenas<'a> {
|
||||||
|
@ -1097,6 +1098,7 @@ pub struct ResolverArenas<'a> {
|
||||||
name_bindings: arena::TypedArena<NameBinding<'a>>,
|
name_bindings: arena::TypedArena<NameBinding<'a>>,
|
||||||
import_directives: arena::TypedArena<ImportDirective<'a>>,
|
import_directives: arena::TypedArena<ImportDirective<'a>>,
|
||||||
name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
|
name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
|
||||||
|
expansion_data: arena::TypedArena<ExpansionData<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ResolverArenas<'a> {
|
impl<'a> ResolverArenas<'a> {
|
||||||
|
@ -1120,6 +1122,9 @@ impl<'a> ResolverArenas<'a> {
|
||||||
fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
|
fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> {
|
||||||
self.name_resolutions.alloc(Default::default())
|
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> {
|
impl<'a> ty::NodeIdTree for Resolver<'a> {
|
||||||
|
@ -1206,7 +1211,8 @@ impl<'a> Resolver<'a> {
|
||||||
DefCollector::new(&mut definitions).collect_root();
|
DefCollector::new(&mut definitions).collect_root();
|
||||||
|
|
||||||
let mut expansion_data = FnvHashMap();
|
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 {
|
Resolver {
|
||||||
session: session,
|
session: session,
|
||||||
|
@ -1277,6 +1283,7 @@ impl<'a> Resolver<'a> {
|
||||||
name_bindings: arena::TypedArena::new(),
|
name_bindings: arena::TypedArena::new(),
|
||||||
import_directives: arena::TypedArena::new(),
|
import_directives: arena::TypedArena::new(),
|
||||||
name_resolutions: arena::TypedArena::new(),
|
name_resolutions: arena::TypedArena::new(),
|
||||||
|
expansion_data: arena::TypedArena::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ use {Module, Resolver};
|
||||||
use build_reduced_graph::BuildReducedGraphVisitor;
|
use build_reduced_graph::BuildReducedGraphVisitor;
|
||||||
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
|
use rustc::hir::def_id::{CRATE_DEF_INDEX, DefIndex};
|
||||||
use rustc::hir::map::{self, DefCollector};
|
use rustc::hir::map::{self, DefCollector};
|
||||||
|
use std::cell::Cell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::errors::DiagnosticBuilder;
|
use syntax::errors::DiagnosticBuilder;
|
||||||
|
@ -35,7 +36,7 @@ pub struct NameBinding {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ExpansionData<'a> {
|
pub struct ExpansionData<'a> {
|
||||||
backtrace: SyntaxContext,
|
backtrace: SyntaxContext,
|
||||||
pub module: Module<'a>,
|
pub module: Cell<Module<'a>>,
|
||||||
def_index: DefIndex,
|
def_index: DefIndex,
|
||||||
// True if this expansion is in a `const_integer` position, for example `[u32; m!()]`.
|
// True if this expansion is in a `const_integer` position, for example `[u32; m!()]`.
|
||||||
// c.f. `DefCollector::visit_ast_const_integer`.
|
// c.f. `DefCollector::visit_ast_const_integer`.
|
||||||
|
@ -46,7 +47,7 @@ impl<'a> ExpansionData<'a> {
|
||||||
pub fn root(graph_root: Module<'a>) -> Self {
|
pub fn root(graph_root: Module<'a>) -> Self {
|
||||||
ExpansionData {
|
ExpansionData {
|
||||||
backtrace: SyntaxContext::empty(),
|
backtrace: SyntaxContext::empty(),
|
||||||
module: graph_root,
|
module: Cell::new(graph_root),
|
||||||
def_index: CRATE_DEF_INDEX,
|
def_index: CRATE_DEF_INDEX,
|
||||||
const_integer: false,
|
const_integer: false,
|
||||||
}
|
}
|
||||||
|
@ -61,18 +62,18 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark {
|
fn get_module_scope(&mut self, id: ast::NodeId) -> Mark {
|
||||||
let mark = Mark::fresh();
|
let mark = Mark::fresh();
|
||||||
let module = self.module_map[&id];
|
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(),
|
backtrace: SyntaxContext::empty(),
|
||||||
module: module,
|
module: Cell::new(module),
|
||||||
def_index: module.def_id().unwrap().index,
|
def_index: module.def_id().unwrap().index,
|
||||||
const_integer: false,
|
const_integer: false,
|
||||||
});
|
}));
|
||||||
mark
|
mark
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
|
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
|
||||||
self.collect_def_ids(mark, 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 });
|
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`");
|
self.session.span_err(def.span, "user-defined macros may not be named `macro_rules`");
|
||||||
}
|
}
|
||||||
if def.use_locally {
|
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 {
|
while module.macros_escape {
|
||||||
module = module.parent.unwrap();
|
module = module.parent.unwrap();
|
||||||
}
|
}
|
||||||
let binding = NameBinding {
|
let binding = NameBinding {
|
||||||
ext: Rc::new(macro_rules::compile(&self.session.parse_sess, &def)),
|
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(),
|
shadowing: self.resolve_macro_name(scope, def.ident.name, false).is_some(),
|
||||||
span: def.span,
|
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> {
|
fn find_attr_invoc(&mut self, attrs: &mut Vec<ast::Attribute>) -> Option<ast::Attribute> {
|
||||||
for i in 0..attrs.len() {
|
for i in 0..attrs.len() {
|
||||||
let name = intern(&attrs[i].name());
|
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 {
|
Some(binding) => match *binding.ext {
|
||||||
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
|
MultiModifier(..) | MultiDecorator(..) | SyntaxExtension::AttrProcMacro(..) => {
|
||||||
return Some(attrs.remove(i))
|
return Some(attrs.remove(i))
|
||||||
|
@ -164,10 +166,11 @@ impl<'a> base::Resolver for Resolver<'a> {
|
||||||
impl<'a> Resolver<'a> {
|
impl<'a> Resolver<'a> {
|
||||||
pub fn resolve_macro_name(&mut self, scope: Mark, name: ast::Name, record_used: bool)
|
pub fn resolve_macro_name(&mut self, scope: Mark, name: ast::Name, record_used: bool)
|
||||||
-> Option<Rc<SyntaxExtension>> {
|
-> 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 {
|
loop {
|
||||||
if let Some(binding) = module.macros.borrow().get(&name) {
|
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 {
|
while binding.expansion != backtrace.outer_mark {
|
||||||
if backtrace.outer_mark != Mark::root() {
|
if backtrace.outer_mark != Mark::root() {
|
||||||
backtrace = backtrace.prev_ctxt.data();
|
backtrace = backtrace.prev_ctxt.data();
|
||||||
|
@ -205,14 +208,18 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_def_ids(&mut self, mark: Mark, expansion: &Expansion) {
|
fn collect_def_ids(&mut self, mark: Mark, expansion: &Expansion) {
|
||||||
let expansion_data = &mut self.expansion_data;
|
let Resolver { ref mut expansion_data, arenas, graph_root, .. } = *self;
|
||||||
let ExpansionData { backtrace, def_index, const_integer, module } = expansion_data[&mark];
|
let ExpansionData { def_index, const_integer, backtrace, .. } =
|
||||||
|
expansion_data[&mark].clone();
|
||||||
|
|
||||||
let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
|
let visit_macro_invoc = &mut |invoc: map::MacroInvocationData| {
|
||||||
expansion_data.entry(invoc.mark).or_insert(ExpansionData {
|
expansion_data.entry(invoc.mark).or_insert_with(|| {
|
||||||
backtrace: backtrace.apply_mark(invoc.mark),
|
arenas.alloc_expansion_data(ExpansionData {
|
||||||
def_index: invoc.def_index,
|
backtrace: backtrace.apply_mark(invoc.mark),
|
||||||
const_integer: invoc.const_integer,
|
def_index: invoc.def_index,
|
||||||
module: module,
|
const_integer: invoc.const_integer,
|
||||||
|
module: Cell::new(graph_root),
|
||||||
|
})
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue