From ea68bc85e01c17bdef5a593188d7a185c6014302 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 13 Aug 2019 01:39:10 +0300 Subject: [PATCH] resolve: Make `ParentScope` `Copy` By allocating its derive paths on the resolver arena. --- src/librustc_resolve/build_reduced_graph.rs | 17 ++++++------- src/librustc_resolve/diagnostics.rs | 4 +-- src/librustc_resolve/lib.rs | 14 +++++++---- src/librustc_resolve/macros.rs | 28 ++++++++++----------- src/librustc_resolve/resolve_imports.rs | 2 +- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 51a0a7456885..bfb7844b543c 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -300,10 +300,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { root_id: NodeId, vis: ty::Visibility, ) { - let parent_scope = &self.parent_scope; - let current_module = parent_scope.module; + let current_module = self.parent_scope.module; let directive = self.r.arenas.alloc_import_directive(ImportDirective { - parent_scope: parent_scope.clone(), + parent_scope: self.parent_scope, module_path, imported_module: Cell::new(None), subclass, @@ -601,7 +600,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let directive = self.r.arenas.alloc_import_directive(ImportDirective { root_id: item.id, id: item.id, - parent_scope: self.parent_scope.clone(), + parent_scope: self.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::ExternCrate { source: orig_name, @@ -994,7 +993,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { |this: &Self, span| this.r.arenas.alloc_import_directive(ImportDirective { root_id: item.id, id: item.id, - parent_scope: this.parent_scope.clone(), + parent_scope: this.parent_scope, imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::MacroUse, use_span_with_attributes: item.span_with_attributes(), @@ -1066,11 +1065,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> { let invoc_id = id.placeholder_to_expn_id(); - let parent_scope = self.parent_scope.clone(); - parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); + self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); - let old_parent_scope = - self.r.invocation_parent_scopes.insert(invoc_id, parent_scope.clone()); + let old_parent_scope = self.r.invocation_parent_scopes.insert(invoc_id, self.parent_scope); assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation"); LegacyScope::Invocation(invoc_id) @@ -1261,7 +1258,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { fn visit_attribute(&mut self, attr: &'b ast::Attribute) { if !attr.is_sugared_doc && is_builtin_attr(attr) { - self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope.clone())); + self.r.builtin_attrs.push((attr.path.segments[0].ident, self.parent_scope)); } visit::walk_attribute(self, attr); } diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index f824dfe8e781..8ec5d64ef3d0 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -376,9 +376,9 @@ impl<'a> Resolver<'a> { Scope::DeriveHelpers => { let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); if filter_fn(res) { - for derive in &parent_scope.derives { + for derive in parent_scope.derives { let parent_scope = - &ParentScope { derives: Vec::new(), ..*parent_scope }; + &ParentScope { derives: &[], ..*parent_scope }; if let Ok((Some(ext), _)) = this.resolve_macro_path( derive, Some(MacroKind::Derive), parent_scope, false, false ) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 85f8d07bf9bd..b0944b480a2d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -122,12 +122,12 @@ enum ScopeSet { /// Serves as a starting point for the scope visitor. /// This struct is currently used only for early resolution (imports and macros), /// but not for late resolution yet. -#[derive(Clone, Debug)] +#[derive(Clone, Copy, Debug)] pub struct ParentScope<'a> { module: Module<'a>, expansion: ExpnId, legacy: LegacyScope<'a>, - derives: Vec, + derives: &'a [ast::Path], } impl<'a> ParentScope<'a> { @@ -136,7 +136,7 @@ impl<'a> ParentScope<'a> { module, expansion: ExpnId::root(), legacy: LegacyScope::Empty, - derives: Vec::new(), + derives: &[], } } } @@ -940,6 +940,7 @@ pub struct ResolverArenas<'a> { import_directives: arena::TypedArena>, name_resolutions: arena::TypedArena>>, legacy_bindings: arena::TypedArena>, + ast_paths: arena::TypedArena, } impl<'a> ResolverArenas<'a> { @@ -966,6 +967,9 @@ impl<'a> ResolverArenas<'a> { fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> { self.legacy_bindings.alloc(binding) } + fn alloc_ast_paths(&'a self, paths: &[ast::Path]) -> &'a [ast::Path] { + self.ast_paths.alloc_from_iter(paths.iter().cloned()) + } } impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> { @@ -1515,7 +1519,7 @@ impl<'a> Resolver<'a> { self.hygienic_lexical_parent(module, &mut ident.span) }; module = unwrap_or!(opt_module, break); - let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() }; + let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; let result = self.resolve_ident_in_module_unadjusted( ModuleOrUniformRoot::Module(module), ident, @@ -1651,7 +1655,7 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(m) => { if let Some(def) = ident.span.modernize_and_adjust(m.expansion) { tmp_parent_scope = - ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() }; + ParentScope { module: self.macro_def_scope(def), ..*parent_scope }; adjusted_parent_scope = &tmp_parent_scope; } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index e64ca61b7efd..dd8e34070311 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -118,11 +118,9 @@ impl<'a> base::Resolver for Resolver<'a> { &mut self, expansion: ExpnId, fragment: &AstFragment, derives: &[ExpnId] ) { // Fill in some data for derives if the fragment is from a derive container. - let parent_scope = self.invocation_parent_scopes[&expansion].clone(); + let parent_scope = self.invocation_parent_scopes[&expansion]; let parent_def = self.definitions.invocation_parent(expansion); - self.invocation_parent_scopes.extend( - derives.iter().map(|&derive| (derive, parent_scope.clone())) - ); + self.invocation_parent_scopes.extend(derives.iter().map(|&derive| (derive, parent_scope))); for &derive_invoc_id in derives { self.definitions.set_invocation_parent(derive_invoc_id, parent_def); } @@ -152,14 +150,14 @@ impl<'a> base::Resolver for Resolver<'a> { fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool) -> Result>, Indeterminate> { - let parent_scope = &self.invocation_parent_scopes[&invoc_id].clone(); + let parent_scope = self.invocation_parent_scopes[&invoc_id]; let (path, kind, derives, after_derive) = match invoc.kind { InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => - (&attr.path, MacroKind::Attr, derives.clone(), after_derive), + (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive), InvocationKind::Bang { ref mac, .. } => - (&mac.path, MacroKind::Bang, Vec::new(), false), + (&mac.path, MacroKind::Bang, &[][..], false), InvocationKind::Derive { ref path, .. } => - (path, MacroKind::Derive, Vec::new(), false), + (path, MacroKind::Derive, &[][..], false), InvocationKind::DeriveContainer { ref derives, .. } => { // Block expansion of derives in the container until we know whether one of them // is a built-in `Copy`. Skip the resolution if there's only one derive - either @@ -169,7 +167,7 @@ impl<'a> base::Resolver for Resolver<'a> { if derives.len() > 1 { for path in derives { match self.resolve_macro_path(path, Some(MacroKind::Derive), - parent_scope, true, force) { + &parent_scope, true, force) { Ok((Some(ref ext), _)) if ext.is_derive_copy => { self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY); return Ok(None); @@ -184,7 +182,7 @@ impl<'a> base::Resolver for Resolver<'a> { }; // Derives are not included when `invocations` are collected, so we have to add them here. - let parent_scope = &ParentScope { derives, ..parent_scope.clone() }; + let parent_scope = &ParentScope { derives, ..parent_scope }; let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); @@ -324,7 +322,7 @@ impl<'a> Resolver<'a> { if trace { let kind = kind.expect("macro kind must be specified if tracing is enabled"); self.multi_segment_macro_resolutions - .push((path, path_span, kind, parent_scope.clone(), res.ok())); + .push((path, path_span, kind, *parent_scope, res.ok())); } self.prohibit_imported_non_macro_attrs(None, res.ok(), path_span); @@ -341,7 +339,7 @@ impl<'a> Resolver<'a> { if trace { let kind = kind.expect("macro kind must be specified if tracing is enabled"); self.single_segment_macro_resolutions - .push((path[0].ident, kind, parent_scope.clone(), binding.ok())); + .push((path[0].ident, kind, *parent_scope, binding.ok())); } let res = binding.map(|binding| binding.res()); @@ -410,8 +408,8 @@ impl<'a> Resolver<'a> { let result = match scope { Scope::DeriveHelpers => { let mut result = Err(Determinacy::Determined); - for derive in &parent_scope.derives { - let parent_scope = &ParentScope { derives: Vec::new(), ..*parent_scope }; + for derive in parent_scope.derives { + let parent_scope = &ParentScope { derives: &[], ..*parent_scope }; match this.resolve_macro_path(derive, Some(MacroKind::Derive), parent_scope, true, force) { Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) { @@ -457,7 +455,7 @@ impl<'a> Resolver<'a> { } } Scope::Module(module) => { - let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() }; + let adjusted_parent_scope = &ParentScope { module, ..*parent_scope }; let binding = this.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(module), ident, diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index ef8fcc9ba8a5..0e3bdc1274a6 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -394,7 +394,7 @@ impl<'a> Resolver<'a> { match ident.span.glob_adjust(module.expansion, glob_import.span) { Some(Some(def)) => { tmp_parent_scope = - ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() }; + ParentScope { module: self.macro_def_scope(def), ..*parent_scope }; adjusted_parent_scope = &tmp_parent_scope; } Some(None) => {}