diff options
| author | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-10-08 00:30:24 +0000 |
|---|---|---|
| committer | Jeffrey Seyfried <jeffrey.seyfried@gmail.com> | 2016-10-10 09:35:25 +0000 |
| commit | 53fd3b0acc42c8c038382bcbc5e4ba7869178228 (patch) | |
| tree | f4c5b90d6f01f8ae1a0372aa4e4769cb79ff15aa | |
| parent | fbc96e18ad0c2a3f5be7e4ef003c720146b0a52d (diff) | |
| download | rust-53fd3b0acc42c8c038382bcbc5e4ba7869178228.tar.gz rust-53fd3b0acc42c8c038382bcbc5e4ba7869178228.zip | |
Avoid quadratic complexity.
| -rw-r--r-- | src/librustc_resolve/macros.rs | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 31b0180f6f1..4ee07036edb 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -60,6 +60,19 @@ 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> { parent: LegacyScope<'a>, kind: LegacyBindingKind, @@ -175,8 +188,11 @@ impl<'a> base::Resolver for Resolver<'a> { InvocationKind::Attr { ref attr, .. } => (intern(&*attr.name()), attr.span), }; - let scope = self.invocations[&scope].legacy_scope.get(); - self.resolve_macro_name(scope, name, true).or_else(|| { + let invocation = self.invocations[&scope]; + if let LegacyScope::Expansion(parent) = invocation.legacy_scope.get() { + invocation.legacy_scope.set(LegacyScope::simplify_expansion(parent)); + } + self.resolve_macro_name(invocation.legacy_scope.get(), name, true).or_else(|| { let mut err = self.session.struct_span_err(span, &format!("macro undefined: '{}!'", name)); self.suggest_macro_name(&name.as_str(), &mut err); |
