Auto merge of #37951 - jseyfried:improve_macro_resolution_perf, r=nrc
macros: improve resolution performance Avoid quadratic legacy macro name resolution in more cases. r? @nrc
This commit is contained in:
commit
d9bdc636da
@ -1137,7 +1137,7 @@ pub struct Resolver<'a> {
|
||||
crate_loader: &'a mut CrateLoader,
|
||||
macro_names: FxHashSet<Name>,
|
||||
builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
|
||||
lexical_macro_resolutions: Vec<(Name, LegacyScope<'a>)>,
|
||||
lexical_macro_resolutions: Vec<(Name, &'a Cell<LegacyScope<'a>>)>,
|
||||
macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
|
||||
macro_exports: Vec<Export>,
|
||||
|
||||
@ -3419,7 +3419,7 @@ fn report_shadowing_errors(&mut self) {
|
||||
|
||||
let mut reported_errors = FxHashSet();
|
||||
for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
|
||||
if self.resolve_legacy_scope(binding.parent, binding.name, false).is_some() &&
|
||||
if self.resolve_legacy_scope(&binding.parent, binding.name, false).is_some() &&
|
||||
reported_errors.insert((binding.name, binding.span)) {
|
||||
let msg = format!("`{}` is already in scope", binding.name);
|
||||
self.session.struct_span_err(binding.span, &msg)
|
||||
|
@ -66,21 +66,8 @@ pub enum LegacyScope<'a> {
|
||||
Binding(&'a LegacyBinding<'a>),
|
||||
}
|
||||
|
||||
impl<'a> LegacyScope<'a> {
|
||||
fn simplify_expansion(mut invoc: &'a InvocationData<'a>) -> Self {
|
||||
while let LegacyScope::Invocation(_) = invoc.expansion.get() {
|
||||
match invoc.legacy_scope.get() {
|
||||
LegacyScope::Expansion(new_invoc) => invoc = new_invoc,
|
||||
LegacyScope::Binding(_) => break,
|
||||
scope @ _ => return scope,
|
||||
}
|
||||
}
|
||||
LegacyScope::Expansion(invoc)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LegacyBinding<'a> {
|
||||
pub parent: LegacyScope<'a>,
|
||||
pub parent: Cell<LegacyScope<'a>>,
|
||||
pub name: ast::Name,
|
||||
ext: Rc<SyntaxExtension>,
|
||||
pub span: Span,
|
||||
@ -157,7 +144,7 @@ fn add_macro(&mut self, scope: Mark, mut def: ast::MacroDef, export: bool) {
|
||||
|
||||
let invocation = self.invocations[&scope];
|
||||
let binding = self.arenas.alloc_legacy_binding(LegacyBinding {
|
||||
parent: invocation.legacy_scope.get(),
|
||||
parent: Cell::new(invocation.legacy_scope.get()),
|
||||
name: def.ident.name,
|
||||
ext: Rc::new(macro_rules::compile(&self.session.parse_sess, &def)),
|
||||
span: def.span,
|
||||
@ -228,12 +215,8 @@ fn resolve_macro(&mut self, scope: Mark, path: &ast::Path, force: bool)
|
||||
let name = path.segments[0].identifier.name;
|
||||
|
||||
let invocation = self.invocations[&scope];
|
||||
if let LegacyScope::Expansion(parent) = invocation.legacy_scope.get() {
|
||||
invocation.legacy_scope.set(LegacyScope::simplify_expansion(parent));
|
||||
}
|
||||
|
||||
self.current_module = invocation.module.get();
|
||||
let result = match self.resolve_legacy_scope(invocation.legacy_scope.get(), name, false) {
|
||||
let result = match self.resolve_legacy_scope(&invocation.legacy_scope, name, false) {
|
||||
Some(MacroBinding::Legacy(binding)) => Ok(binding.ext.clone()),
|
||||
Some(MacroBinding::Modern(binding)) => Ok(self.get_macro(binding)),
|
||||
None => match self.resolve_in_item_lexical_scope(name, MacroNS, None) {
|
||||
@ -299,7 +282,7 @@ fn resolve_in_item_lexical_scope(&mut self,
|
||||
}
|
||||
|
||||
pub fn resolve_legacy_scope(&mut self,
|
||||
mut scope: LegacyScope<'a>,
|
||||
mut scope: &'a Cell<LegacyScope<'a>>,
|
||||
name: Name,
|
||||
record_used: bool)
|
||||
-> Option<MacroBinding<'a>> {
|
||||
@ -307,22 +290,26 @@ pub fn resolve_legacy_scope(&mut self,
|
||||
let mut relative_depth: u32 = 0;
|
||||
let mut binding = None;
|
||||
loop {
|
||||
scope = match scope {
|
||||
match scope.get() {
|
||||
LegacyScope::Empty => break,
|
||||
LegacyScope::Expansion(invocation) => {
|
||||
if let LegacyScope::Empty = invocation.expansion.get() {
|
||||
if possible_time_travel.is_none() {
|
||||
possible_time_travel = Some(scope);
|
||||
match invocation.expansion.get() {
|
||||
LegacyScope::Invocation(_) => scope.set(invocation.legacy_scope.get()),
|
||||
LegacyScope::Empty => {
|
||||
if possible_time_travel.is_none() {
|
||||
possible_time_travel = Some(scope);
|
||||
}
|
||||
scope = &invocation.legacy_scope;
|
||||
}
|
||||
_ => {
|
||||
relative_depth += 1;
|
||||
scope = &invocation.expansion;
|
||||
}
|
||||
invocation.legacy_scope.get()
|
||||
} else {
|
||||
relative_depth += 1;
|
||||
invocation.expansion.get()
|
||||
}
|
||||
}
|
||||
LegacyScope::Invocation(invocation) => {
|
||||
relative_depth = relative_depth.saturating_sub(1);
|
||||
invocation.legacy_scope.get()
|
||||
scope = &invocation.legacy_scope;
|
||||
}
|
||||
LegacyScope::Binding(potential_binding) => {
|
||||
if potential_binding.name == name {
|
||||
@ -332,7 +319,7 @@ pub fn resolve_legacy_scope(&mut self,
|
||||
binding = Some(potential_binding);
|
||||
break
|
||||
}
|
||||
potential_binding.parent
|
||||
scope = &potential_binding.parent;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -358,7 +345,7 @@ pub fn resolve_legacy_scope(&mut self,
|
||||
pub fn finalize_current_module_macro_resolutions(&mut self) {
|
||||
let module = self.current_module;
|
||||
for &(mark, name, span) in module.legacy_macro_resolutions.borrow().iter() {
|
||||
let legacy_scope = self.invocations[&mark].legacy_scope.get();
|
||||
let legacy_scope = &self.invocations[&mark].legacy_scope;
|
||||
let legacy_resolution = self.resolve_legacy_scope(legacy_scope, name, true);
|
||||
let resolution = self.resolve_in_item_lexical_scope(name, MacroNS, Some(span));
|
||||
let (legacy_resolution, resolution) = match (legacy_resolution, resolution) {
|
||||
|
Loading…
Reference in New Issue
Block a user