resolve: Make ParentScope Copy

By allocating its derive paths on the resolver arena.
This commit is contained in:
Vadim Petrochenkov 2019-08-13 01:39:10 +03:00
parent 59dd07ae2b
commit ea68bc85e0
5 changed files with 32 additions and 33 deletions

View file

@ -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);
}

View file

@ -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
) {

View file

@ -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<ast::Path>,
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<ImportDirective<'a>>,
name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>,
legacy_bindings: arena::TypedArena<LegacyBinding<'a>>,
ast_paths: arena::TypedArena<ast::Path>,
}
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;
}
}

View file

@ -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<Option<Lrc<SyntaxExtension>>, 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,

View file

@ -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) => {}