From cbe478766cb1cafed8341de2e7fffd3b1f104e70 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 23 Nov 2016 01:51:37 +0000 Subject: [PATCH] macros: improve performance of legacy name resolution. --- src/librustc_resolve/lib.rs | 4 +-- src/librustc_resolve/macros.rs | 51 +++++++++++++--------------------- 2 files changed, 21 insertions(+), 34 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index c72ba7bb687..f30304f2ea4 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1137,7 +1137,7 @@ pub struct Resolver<'a> { crate_loader: &'a mut CrateLoader, macro_names: FxHashSet, builtin_macros: FxHashMap>, - lexical_macro_resolutions: Vec<(Name, LegacyScope<'a>)>, + lexical_macro_resolutions: Vec<(Name, &'a Cell>)>, macro_map: FxHashMap>, macro_exports: Vec, @@ -3416,7 +3416,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) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 62adf382a69..cdb51f459e8 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -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>, pub name: ast::Name, ext: Rc, 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>, name: Name, record_used: bool) -> Option> { @@ -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) {