Use Resolver::visit_expansion only with monotonic expansions.
This commit is contained in:
@@ -1070,7 +1070,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: Vec<macros::ExpansionData>,
|
expansion_data: FnvHashMap<u32, macros::ExpansionData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ResolverArenas<'a> {
|
pub struct ResolverArenas<'a> {
|
||||||
@@ -1184,6 +1184,9 @@ impl<'a> Resolver<'a> {
|
|||||||
let mut module_map = NodeMap();
|
let mut module_map = NodeMap();
|
||||||
module_map.insert(CRATE_NODE_ID, graph_root);
|
module_map.insert(CRATE_NODE_ID, graph_root);
|
||||||
|
|
||||||
|
let mut expansion_data = FnvHashMap();
|
||||||
|
expansion_data.insert(0, macros::ExpansionData::default()); // Crate root expansion
|
||||||
|
|
||||||
Resolver {
|
Resolver {
|
||||||
session: session,
|
session: session,
|
||||||
|
|
||||||
@@ -1239,7 +1242,7 @@ impl<'a> Resolver<'a> {
|
|||||||
|
|
||||||
macro_loader: macro_loader,
|
macro_loader: macro_loader,
|
||||||
macro_names: FnvHashSet(),
|
macro_names: FnvHashSet(),
|
||||||
expansion_data: vec![macros::ExpansionData::default()],
|
expansion_data: expansion_data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
|||||||
|
|
||||||
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
|
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion) {
|
||||||
expansion.visit_with(&mut ExpansionVisitor {
|
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,
|
resolver: self,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -57,7 +57,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
|||||||
self.macro_names.insert(ident.name);
|
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 {
|
while module.macros_escape {
|
||||||
module = module.parent.clone().unwrap();
|
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> {
|
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[0].module.macros.borrow().get(&name) {
|
match self.expansion_data[&0].module.macros.borrow().get(&name) {
|
||||||
Some(ext) => match **ext {
|
Some(ext) => match **ext {
|
||||||
MultiModifier(..) | MultiDecorator(..) => return Some(attrs.remove(i)),
|
MultiModifier(..) | MultiDecorator(..) => return Some(attrs.remove(i)),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -82,7 +82,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
|||||||
None
|
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 {
|
let (name, span) = match invoc.kind {
|
||||||
InvocationKind::Bang { ref mac, .. } => {
|
InvocationKind::Bang { ref mac, .. } => {
|
||||||
let path = &mac.node.path;
|
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),
|
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 {
|
loop {
|
||||||
if let Some(ext) = module.macros.borrow().get(&name) {
|
if let Some(ext) = module.macros.borrow().get(&name) {
|
||||||
return Some(ext.clone());
|
return Some(ext.clone());
|
||||||
@@ -135,8 +135,7 @@ struct ExpansionVisitor<'b, 'a: 'b> {
|
|||||||
|
|
||||||
impl<'a, 'b> ExpansionVisitor<'a, 'b> {
|
impl<'a, 'b> ExpansionVisitor<'a, 'b> {
|
||||||
fn visit_invoc(&mut self, id: ast::NodeId) {
|
fn visit_invoc(&mut self, id: ast::NodeId) {
|
||||||
assert_eq!(id.as_u32(), self.resolver.expansion_data.len() as u32);
|
self.resolver.expansion_data.insert(id.as_u32(), ExpansionData {
|
||||||
self.resolver.expansion_data.push(ExpansionData {
|
|
||||||
module: self.current_module.clone(),
|
module: self.current_module.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -470,7 +470,7 @@ pub trait Resolver {
|
|||||||
fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec<Mark>);
|
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 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 {
|
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 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 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)]
|
#[derive(Clone)]
|
||||||
|
|||||||
@@ -165,10 +165,6 @@ impl Invocation {
|
|||||||
InvocationKind::Attr { ref attr, .. } => attr.span,
|
InvocationKind::Attr { ref attr, .. } => attr.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mark(&self) -> Mark {
|
|
||||||
self.expansion_data.mark
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct MacroExpander<'a, 'b:'a> {
|
pub struct MacroExpander<'a, 'b:'a> {
|
||||||
@@ -219,7 +215,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
let ExpansionData { depth, mark, .. } = invoc.expansion_data;
|
let ExpansionData { depth, mark, .. } = invoc.expansion_data;
|
||||||
self.cx.current_expansion = invoc.expansion_data.clone();
|
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),
|
Some(ext) => self.expand_invoc(invoc, ext),
|
||||||
None => invoc.expansion_kind.dummy(invoc.span()),
|
None => invoc.expansion_kind.dummy(invoc.span()),
|
||||||
};
|
};
|
||||||
@@ -267,8 +265,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
};
|
};
|
||||||
self.cx.cfg = crate_config;
|
self.cx.cfg = crate_config;
|
||||||
|
|
||||||
|
if self.monotonic {
|
||||||
let mark = self.cx.current_expansion.mark;
|
let mark = self.cx.current_expansion.mark;
|
||||||
self.cx.resolver.visit_expansion(mark, &result.0);
|
self.cx.resolver.visit_expansion(mark, &result.0);
|
||||||
|
}
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +315,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||||||
|
|
||||||
/// Expand a macro invocation. Returns the result of expansion.
|
/// Expand a macro invocation. Returns the result of expansion.
|
||||||
fn expand_bang_invoc(&mut self, invoc: Invocation, ext: Rc<SyntaxExtension>) -> 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 {
|
let (attrs, mac, ident, span) = match invoc.kind {
|
||||||
InvocationKind::Bang { attrs, mac, ident, span } => (attrs, mac, ident, span),
|
InvocationKind::Bang { attrs, mac, ident, span } => (attrs, mac, ident, span),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
|||||||
Reference in New Issue
Block a user