diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-08-12 23:39:49 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-08-15 20:40:18 +0300 |
| commit | 59dd07ae2bbc8d6c46bdb5f3d5b93a6729848311 (patch) | |
| tree | 4ff4555f9bd1782872295b7350fa39e278bf26b1 /src | |
| parent | 1a1557c28501d256f3a21099d17a73e1d2c36aa0 (diff) | |
| download | rust-59dd07ae2bbc8d6c46bdb5f3d5b93a6729848311.tar.gz rust-59dd07ae2bbc8d6c46bdb5f3d5b93a6729848311.zip | |
resolve: Eliminate `InvocationData`
It was very similar to `ParentScope` and mostly could be replaced by it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_resolve/build_reduced_graph.rs | 23 | ||||
| -rw-r--r-- | src/librustc_resolve/lib.rs | 29 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 92 |
3 files changed, 53 insertions, 91 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 016ec55947a..51a0a745688 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -3,7 +3,7 @@ //! Here we build the "reduced graph": the graph of the module tree without //! any imports resolved. -use crate::macros::{InvocationData, LegacyBinding, LegacyScope}; +use crate::macros::{LegacyBinding, LegacyScope}; use crate::resolve_imports::ImportDirective; use crate::resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; use crate::{Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; @@ -1063,20 +1063,17 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { false } - fn visit_invoc(&mut self, id: ast::NodeId) -> &'a InvocationData<'a> { + fn visit_invoc(&mut self, id: ast::NodeId) -> LegacyScope<'a> { let invoc_id = id.placeholder_to_expn_id(); - self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); + let parent_scope = self.parent_scope.clone(); + parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id); - let invocation_data = self.r.arenas.alloc_invocation_data(InvocationData { - module: self.parent_scope.module, - parent_legacy_scope: self.parent_scope.legacy, - output_legacy_scope: Cell::new(None), - }); - let old_invocation_data = self.r.invocations.insert(invoc_id, invocation_data); - assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation"); + let old_parent_scope = + self.r.invocation_parent_scopes.insert(invoc_id, parent_scope.clone()); + assert!(old_parent_scope.is_none(), "invocation data is reset for an invocation"); - invocation_data + LegacyScope::Invocation(invoc_id) } fn proc_macro_stub(item: &ast::Item) -> Option<(MacroKind, Ident, Span)> { @@ -1177,7 +1174,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { return } ItemKind::Mac(..) => { - self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(item.id)); + self.parent_scope.legacy = self.visit_invoc(item.id); return } ItemKind::Mod(..) => self.contains_macro_use(&item.attrs), @@ -1196,7 +1193,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { fn visit_stmt(&mut self, stmt: &'b ast::Stmt) { if let ast::StmtKind::Mac(..) = stmt.node { - self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(stmt.id)); + self.parent_scope.legacy = self.visit_invoc(stmt.id); } else { visit::walk_stmt(self, stmt); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 788252c55fc..85f8d07bf9b 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -54,7 +54,7 @@ use diagnostics::{Suggestion, ImportSuggestion}; use diagnostics::{find_span_of_binding_until_next_binding, extend_span_to_previous_binding}; use late::{PathSource, Rib, RibKind::*}; use resolve_imports::{ImportDirective, ImportDirectiveSubclass, NameResolution, ImportResolver}; -use macros::{InvocationData, LegacyBinding, LegacyScope}; +use macros::{LegacyBinding, LegacyScope}; type Res = def::Res<NodeId>; @@ -911,9 +911,12 @@ pub struct Resolver<'a> { /// FIXME: Find a way for `PartialEq` and `Eq` to emulate `#[structural_match]` /// by marking the produced impls rather than the original items. special_derives: FxHashMap<ExpnId, SpecialDerives>, - - /// Maps the `ExpnId` of an expansion to its containing module or block. - invocations: FxHashMap<ExpnId, &'a InvocationData<'a>>, + /// Parent scopes in which the macros were invoked. + /// FIXME: `derives` are missing in these parent scopes and need to be taken from elsewhere. + invocation_parent_scopes: FxHashMap<ExpnId, ParentScope<'a>>, + /// Legacy scopes *produced* by expanding the macro invocations, + /// include all the `macro_rules` items and other invocations generated by them. + output_legacy_scopes: FxHashMap<ExpnId, LegacyScope<'a>>, /// Avoid duplicated errors for "name already defined". name_already_seen: FxHashMap<Name, Span>, @@ -936,7 +939,6 @@ pub struct ResolverArenas<'a> { name_bindings: arena::TypedArena<NameBinding<'a>>, import_directives: arena::TypedArena<ImportDirective<'a>>, name_resolutions: arena::TypedArena<RefCell<NameResolution<'a>>>, - invocation_data: arena::TypedArena<InvocationData<'a>>, legacy_bindings: arena::TypedArena<LegacyBinding<'a>>, } @@ -961,10 +963,6 @@ impl<'a> ResolverArenas<'a> { fn alloc_name_resolution(&'a self) -> &'a RefCell<NameResolution<'a>> { self.name_resolutions.alloc(Default::default()) } - fn alloc_invocation_data(&'a self, expansion_data: InvocationData<'a>) - -> &'a InvocationData<'a> { - self.invocation_data.alloc(expansion_data) - } fn alloc_legacy_binding(&'a self, binding: LegacyBinding<'a>) -> &'a LegacyBinding<'a> { self.legacy_bindings.alloc(binding) } @@ -1078,9 +1076,8 @@ impl<'a> Resolver<'a> { } } - let mut invocations = FxHashMap::default(); - invocations.insert(ExpnId::root(), - arenas.alloc_invocation_data(InvocationData::default(graph_root))); + let mut invocation_parent_scopes = FxHashMap::default(); + invocation_parent_scopes.insert(ExpnId::root(), ParentScope::default(graph_root)); let mut macro_defs = FxHashMap::default(); macro_defs.insert(ExpnId::root(), root_def_id); @@ -1152,7 +1149,8 @@ impl<'a> Resolver<'a> { dummy_ext_bang: Lrc::new(SyntaxExtension::dummy_bang(session.edition())), dummy_ext_derive: Lrc::new(SyntaxExtension::dummy_derive(session.edition())), non_macro_attrs: [non_macro_attr(false), non_macro_attr(true)], - invocations, + invocation_parent_scopes, + output_legacy_scopes: Default::default(), macro_defs, local_macro_def_scopes: FxHashMap::default(), name_already_seen: FxHashMap::default(), @@ -1370,8 +1368,9 @@ impl<'a> Resolver<'a> { LegacyScope::Binding(binding) => Scope::MacroRules( binding.parent_legacy_scope ), - LegacyScope::Invocation(invoc) => Scope::MacroRules( - invoc.output_legacy_scope.get().unwrap_or(invoc.parent_legacy_scope) + LegacyScope::Invocation(invoc_id) => Scope::MacroRules( + self.output_legacy_scopes.get(&invoc_id).cloned() + .unwrap_or(self.invocation_parent_scopes[&invoc_id].legacy) ), LegacyScope::Empty => Scope::Module(module), } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 754983e3bd4..e64ca61b7ef 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -1,6 +1,6 @@ use crate::{AmbiguityError, AmbiguityKind, AmbiguityErrorMisc, Determinacy}; use crate::{CrateLint, Resolver, ResolutionError, Scope, ScopeSet, ParentScope, Weak}; -use crate::{Module, ModuleKind, NameBinding, PathResult, Segment, ToNameBinding}; +use crate::{ModuleKind, NameBinding, PathResult, Segment, ToNameBinding}; use crate::{ModuleOrUniformRoot, KNOWN_TOOLS}; use crate::Namespace::*; use crate::build_reduced_graph::BuildReducedGraphVisitor; @@ -22,36 +22,11 @@ use syntax::feature_gate::GateIssue; use syntax::symbol::{Symbol, kw, sym}; use syntax_pos::{Span, DUMMY_SP}; -use std::cell::Cell; use std::{mem, ptr}; use rustc_data_structures::sync::Lrc; type Res = def::Res<ast::NodeId>; -// FIXME: Merge this with `ParentScope`. -#[derive(Clone, Debug)] -pub struct InvocationData<'a> { - /// The module in which the macro was invoked. - crate module: Module<'a>, - /// The legacy scope in which the macro was invoked. - /// The invocation path is resolved in this scope. - crate parent_legacy_scope: LegacyScope<'a>, - /// The legacy scope *produced* by expanding this macro invocation, - /// includes all the macro_rules items, other invocations, etc generated by it. - /// `None` if the macro is not expanded yet. - crate output_legacy_scope: Cell<Option<LegacyScope<'a>>>, -} - -impl<'a> InvocationData<'a> { - pub fn default(module: Module<'a>) -> Self { - InvocationData { - module, - parent_legacy_scope: LegacyScope::Empty, - output_legacy_scope: Cell::new(None), - } - } -} - /// Binding produced by a `macro_rules` item. /// Not modularized, can shadow previous legacy bindings, etc. #[derive(Debug)] @@ -75,7 +50,7 @@ pub enum LegacyScope<'a> { Binding(&'a LegacyBinding<'a>), /// The scope introduced by a macro invocation that can potentially /// create a `macro_rules!` macro definition. - Invocation(&'a InvocationData<'a>), + Invocation(ExpnId), } // Macro namespace is separated into two sub-namespaces, one for bang macros and @@ -124,9 +99,8 @@ impl<'a> base::Resolver for Resolver<'a> { ExpnKind::Macro(MacroKind::Attr, sym::test_case), DUMMY_SP, self.session.edition() ))); let module = self.module_map[&self.definitions.local_def_id(id)]; - let invocation_data = self.arenas.alloc_invocation_data(InvocationData::default(module)); + self.invocation_parent_scopes.insert(expn_id, ParentScope::default(module)); self.definitions.set_invocation_parent(expn_id, module.def_id().unwrap().index); - self.invocations.insert(expn_id, invocation_data); expn_id } @@ -140,29 +114,29 @@ impl<'a> base::Resolver for Resolver<'a> { }); } - fn visit_ast_fragment_with_placeholders(&mut self, expn_id: ExpnId, fragment: &AstFragment, - derives: &[ExpnId]) { - fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expn_id)); - - let invocation = self.invocations[&expn_id]; - invocation.module.unresolved_invocations.borrow_mut().remove(&expn_id); - invocation.module.unresolved_invocations.borrow_mut().extend(derives); - let parent_def = self.definitions.invocation_parent(expn_id); + fn visit_ast_fragment_with_placeholders( + &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_def = self.definitions.invocation_parent(expansion); + self.invocation_parent_scopes.extend( + derives.iter().map(|&derive| (derive, parent_scope.clone())) + ); for &derive_invoc_id in derives { self.definitions.set_invocation_parent(derive_invoc_id, parent_def); } - self.invocations.extend(derives.iter().map(|&derive| (derive, invocation))); - let mut visitor = BuildReducedGraphVisitor { - r: self, - parent_scope: ParentScope { - module: invocation.module, - expansion: expn_id, - legacy: invocation.parent_legacy_scope, - derives: Vec::new(), - }, - }; + parent_scope.module.unresolved_invocations.borrow_mut().remove(&expansion); + parent_scope.module.unresolved_invocations.borrow_mut().extend(derives); + + // Integrate the new AST fragment into all the definition and module structures. + // We are inside the `expansion` new, but other parent scope components are still the same. + fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expansion)); + let parent_scope = ParentScope { expansion, ..parent_scope }; + let mut visitor = BuildReducedGraphVisitor { r: self, parent_scope }; fragment.visit_with(&mut visitor); - invocation.output_legacy_scope.set(Some(visitor.parent_scope.legacy)); + let output_legacy_scope = visitor.parent_scope.legacy; + self.output_legacy_scopes.insert(expansion, output_legacy_scope); } fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) { @@ -178,7 +152,8 @@ 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 (path, kind, derives_in_scope, after_derive) = match invoc.kind { + let parent_scope = &self.invocation_parent_scopes[&invoc_id].clone(); + 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), InvocationKind::Bang { ref mac, .. } => @@ -192,7 +167,6 @@ impl<'a> base::Resolver for Resolver<'a> { // will automatically knows about itself. let mut result = Ok(None); if derives.len() > 1 { - let parent_scope = &self.invoc_parent_scope(invoc_id, Vec::new()); for path in derives { match self.resolve_macro_path(path, Some(MacroKind::Derive), parent_scope, true, force) { @@ -209,7 +183,8 @@ impl<'a> base::Resolver for Resolver<'a> { } }; - let parent_scope = &self.invoc_parent_scope(invoc_id, derives_in_scope); + // Derives are not included when `invocations` are collected, so we have to add them here. + let parent_scope = &ParentScope { derives, ..parent_scope.clone() }; let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); @@ -247,16 +222,6 @@ impl<'a> base::Resolver for Resolver<'a> { } impl<'a> Resolver<'a> { - fn invoc_parent_scope(&self, invoc_id: ExpnId, derives: Vec<ast::Path>) -> ParentScope<'a> { - let invoc = self.invocations[&invoc_id]; - ParentScope { - module: invoc.module, - expansion: invoc_id.parent(), - legacy: invoc.parent_legacy_scope, - derives, - } - } - /// Resolve macro path with error reporting and recovery. fn smart_resolve_macro_path( &mut self, @@ -466,8 +431,9 @@ impl<'a> Resolver<'a> { Scope::MacroRules(legacy_scope) => match legacy_scope { LegacyScope::Binding(legacy_binding) if ident == legacy_binding.ident => Ok((legacy_binding.binding, Flags::MACRO_RULES)), - LegacyScope::Invocation(invoc) if invoc.output_legacy_scope.get().is_none() => - Err(Determinacy::Undetermined), + LegacyScope::Invocation(invoc_id) + if !this.output_legacy_scopes.contains_key(&invoc_id) => + Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), } Scope::CrateRoot => { |
