Skip to content

Commit d9bdc63

Browse files
authored
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
2 parents a31ad75 + cbe4787 commit d9bdc63

File tree

2 files changed

+21
-34
lines changed

2 files changed

+21
-34
lines changed

src/librustc_resolve/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ pub struct Resolver<'a> {
11371137
crate_loader: &'a mut CrateLoader,
11381138
macro_names: FxHashSet<Name>,
11391139
builtin_macros: FxHashMap<Name, &'a NameBinding<'a>>,
1140-
lexical_macro_resolutions: Vec<(Name, LegacyScope<'a>)>,
1140+
lexical_macro_resolutions: Vec<(Name, &'a Cell<LegacyScope<'a>>)>,
11411141
macro_map: FxHashMap<DefId, Rc<SyntaxExtension>>,
11421142
macro_exports: Vec<Export>,
11431143

@@ -3419,7 +3419,7 @@ impl<'a> Resolver<'a> {
34193419

34203420
let mut reported_errors = FxHashSet();
34213421
for binding in replace(&mut self.disallowed_shadowing, Vec::new()) {
3422-
if self.resolve_legacy_scope(binding.parent, binding.name, false).is_some() &&
3422+
if self.resolve_legacy_scope(&binding.parent, binding.name, false).is_some() &&
34233423
reported_errors.insert((binding.name, binding.span)) {
34243424
let msg = format!("`{}` is already in scope", binding.name);
34253425
self.session.struct_span_err(binding.span, &msg)

src/librustc_resolve/macros.rs

+19-32
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,8 @@ pub enum LegacyScope<'a> {
6666
Binding(&'a LegacyBinding<'a>),
6767
}
6868

69-
impl<'a> LegacyScope<'a> {
70-
fn simplify_expansion(mut invoc: &'a InvocationData<'a>) -> Self {
71-
while let LegacyScope::Invocation(_) = invoc.expansion.get() {
72-
match invoc.legacy_scope.get() {
73-
LegacyScope::Expansion(new_invoc) => invoc = new_invoc,
74-
LegacyScope::Binding(_) => break,
75-
scope @ _ => return scope,
76-
}
77-
}
78-
LegacyScope::Expansion(invoc)
79-
}
80-
}
81-
8269
pub struct LegacyBinding<'a> {
83-
pub parent: LegacyScope<'a>,
70+
pub parent: Cell<LegacyScope<'a>>,
8471
pub name: ast::Name,
8572
ext: Rc<SyntaxExtension>,
8673
pub span: Span,
@@ -157,7 +144,7 @@ impl<'a> base::Resolver for Resolver<'a> {
157144

158145
let invocation = self.invocations[&scope];
159146
let binding = self.arenas.alloc_legacy_binding(LegacyBinding {
160-
parent: invocation.legacy_scope.get(),
147+
parent: Cell::new(invocation.legacy_scope.get()),
161148
name: def.ident.name,
162149
ext: Rc::new(macro_rules::compile(&self.session.parse_sess, &def)),
163150
span: def.span,
@@ -228,12 +215,8 @@ impl<'a> base::Resolver for Resolver<'a> {
228215
let name = path.segments[0].identifier.name;
229216

230217
let invocation = self.invocations[&scope];
231-
if let LegacyScope::Expansion(parent) = invocation.legacy_scope.get() {
232-
invocation.legacy_scope.set(LegacyScope::simplify_expansion(parent));
233-
}
234-
235218
self.current_module = invocation.module.get();
236-
let result = match self.resolve_legacy_scope(invocation.legacy_scope.get(), name, false) {
219+
let result = match self.resolve_legacy_scope(&invocation.legacy_scope, name, false) {
237220
Some(MacroBinding::Legacy(binding)) => Ok(binding.ext.clone()),
238221
Some(MacroBinding::Modern(binding)) => Ok(self.get_macro(binding)),
239222
None => match self.resolve_in_item_lexical_scope(name, MacroNS, None) {
@@ -299,30 +282,34 @@ impl<'a> Resolver<'a> {
299282
}
300283

301284
pub fn resolve_legacy_scope(&mut self,
302-
mut scope: LegacyScope<'a>,
285+
mut scope: &'a Cell<LegacyScope<'a>>,
303286
name: Name,
304287
record_used: bool)
305288
-> Option<MacroBinding<'a>> {
306289
let mut possible_time_travel = None;
307290
let mut relative_depth: u32 = 0;
308291
let mut binding = None;
309292
loop {
310-
scope = match scope {
293+
match scope.get() {
311294
LegacyScope::Empty => break,
312295
LegacyScope::Expansion(invocation) => {
313-
if let LegacyScope::Empty = invocation.expansion.get() {
314-
if possible_time_travel.is_none() {
315-
possible_time_travel = Some(scope);
296+
match invocation.expansion.get() {
297+
LegacyScope::Invocation(_) => scope.set(invocation.legacy_scope.get()),
298+
LegacyScope::Empty => {
299+
if possible_time_travel.is_none() {
300+
possible_time_travel = Some(scope);
301+
}
302+
scope = &invocation.legacy_scope;
303+
}
304+
_ => {
305+
relative_depth += 1;
306+
scope = &invocation.expansion;
316307
}
317-
invocation.legacy_scope.get()
318-
} else {
319-
relative_depth += 1;
320-
invocation.expansion.get()
321308
}
322309
}
323310
LegacyScope::Invocation(invocation) => {
324311
relative_depth = relative_depth.saturating_sub(1);
325-
invocation.legacy_scope.get()
312+
scope = &invocation.legacy_scope;
326313
}
327314
LegacyScope::Binding(potential_binding) => {
328315
if potential_binding.name == name {
@@ -332,7 +319,7 @@ impl<'a> Resolver<'a> {
332319
binding = Some(potential_binding);
333320
break
334321
}
335-
potential_binding.parent
322+
scope = &potential_binding.parent;
336323
}
337324
};
338325
}
@@ -358,7 +345,7 @@ impl<'a> Resolver<'a> {
358345
pub fn finalize_current_module_macro_resolutions(&mut self) {
359346
let module = self.current_module;
360347
for &(mark, name, span) in module.legacy_macro_resolutions.borrow().iter() {
361-
let legacy_scope = self.invocations[&mark].legacy_scope.get();
348+
let legacy_scope = &self.invocations[&mark].legacy_scope;
362349
let legacy_resolution = self.resolve_legacy_scope(legacy_scope, name, true);
363350
let resolution = self.resolve_in_item_lexical_scope(name, MacroNS, Some(span));
364351
let (legacy_resolution, resolution) = match (legacy_resolution, resolution) {

0 commit comments

Comments
 (0)