about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-08 03:44:16 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-10 13:16:06 +0300
commitdf03e420e020c2ccc71bad4f7978b49a1c049435 (patch)
treef0b2ad3399cdb9b069b6124531d528c13ca0fa9a
parentff85d1c2d28e19797b9d9aa67bbdfaf92e015c57 (diff)
downloadrust-df03e420e020c2ccc71bad4f7978b49a1c049435.tar.gz
rust-df03e420e020c2ccc71bad4f7978b49a1c049435.zip
resolve: Track whole parent scope in the visitors
Instead of tracking current module and other components separately.
(`ParentScope` includes the module as a component.)
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs97
-rw-r--r--src/librustc_resolve/late.rs58
-rw-r--r--src/librustc_resolve/late/diagnostics.rs8
-rw-r--r--src/librustc_resolve/macros.rs11
4 files changed, 78 insertions, 96 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index 668daaba643..9f6f36e0aa4 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -332,7 +332,8 @@ impl<'a> Resolver<'a> {
 
 impl<'a> BuildReducedGraphVisitor<'_, 'a> {
     /// Constructs the reduced graph for one item.
-    fn build_reduced_graph_for_item(&mut self, item: &Item, parent_scope: &ParentScope<'a>) {
+    fn build_reduced_graph_for_item(&mut self, item: &Item) {
+        let parent_scope = &self.parent_scope.clone();
         let parent = parent_scope.module;
         let expansion = parent_scope.expansion;
         let ident = item.ident.gensym_if_underscore();
@@ -439,7 +440,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
                 self.module_map.insert(def_id, module);
 
                 // Descend into the module.
-                self.current_module = module;
+                self.parent_scope.module = module;
             }
 
             // Handled in `rustc_metadata::{native_libs,link_args}`
@@ -563,7 +564,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
                                              expansion,
                                              item.span);
                 self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
-                self.current_module = module;
+                self.parent_scope.module = module;
             }
 
             ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(),
@@ -605,7 +606,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
     }
 
     /// Constructs the reduced graph for one foreign item.
-    fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem, expn_id: ExpnId) {
+    fn build_reduced_graph_for_foreign_item(&mut self, item: &ForeignItem) {
         let (res, ns) = match item.node {
             ForeignItemKind::Fn(..) => {
                 (Res::Def(DefKind::Fn, self.definitions.local_def_id(item.id)), ValueNS)
@@ -618,27 +619,23 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
             }
             ForeignItemKind::Macro(_) => unreachable!(),
         };
-        let parent = self.current_module;
-        let parent_scope = &ParentScope {
-            module: self.current_module,
-            expansion: self.expansion,
-            legacy: self.current_legacy_scope,
-            derives: Vec::new(),
-        };
-        let vis = self.resolver.resolve_visibility(&item.vis, parent_scope);
-        self.define(parent, item.ident, ns, (res, vis, item.span, expn_id));
+        let parent = self.parent_scope.module;
+        let expansion = self.parent_scope.expansion;
+        let vis = self.resolver.resolve_visibility(&item.vis, &self.parent_scope);
+        self.define(parent, item.ident, ns, (res, vis, item.span, expansion));
     }
 
-    fn build_reduced_graph_for_block(&mut self, block: &Block, expn_id: ExpnId) {
-        let parent = self.current_module;
+    fn build_reduced_graph_for_block(&mut self, block: &Block) {
+        let parent = self.parent_scope.module;
+        let expansion = self.parent_scope.expansion;
         if self.block_needs_anonymous_module(block) {
             let module = self.new_module(parent,
                                          ModuleKind::Block(block.id),
                                          parent.normal_ancestor_id,
-                                         expn_id,
+                                         expansion,
                                          block.span);
             self.block_map.insert(block.id, module);
-            self.current_module = module; // Descend into the block.
+            self.parent_scope.module = module; // Descend into the block.
         }
     }
 }
@@ -827,7 +824,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
         let mut single_imports = Vec::new();
         for attr in &item.attrs {
             if attr.check_name(sym::macro_use) {
-                if self.current_module.parent.is_some() {
+                if self.parent_scope.module.parent.is_some() {
                     span_err!(self.session, item.span, E0468,
                         "an `extern crate` loading macros must be at the crate root");
                 }
@@ -933,9 +930,7 @@ impl<'a> BuildReducedGraphVisitor<'_, 'a> {
 
 pub struct BuildReducedGraphVisitor<'a, 'b> {
     pub resolver: &'a mut Resolver<'b>,
-    pub current_module: Module<'b>,
-    pub current_legacy_scope: LegacyScope<'b>,
-    pub expansion: ExpnId,
+    pub parent_scope: ParentScope<'b>,
 }
 
 impl<'b> Deref for BuildReducedGraphVisitor<'_, 'b> {
@@ -955,11 +950,11 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
     fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> {
         let invoc_id = id.placeholder_to_expn_id();
 
-        self.current_module.unresolved_invocations.borrow_mut().insert(invoc_id);
+        self.parent_scope.module.unresolved_invocations.borrow_mut().insert(invoc_id);
 
         let invocation_data = self.arenas.alloc_invocation_data(InvocationData {
-            module: self.current_module,
-            parent_legacy_scope: self.current_legacy_scope,
+            module: self.parent_scope.module,
+            parent_legacy_scope: self.parent_scope.legacy,
             output_legacy_scope: Cell::new(None),
         });
         let old_invocation_data = self.invocations.insert(invoc_id, invocation_data);
@@ -988,38 +983,32 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
     method!(visit_ty:        ast::Ty,       ast::TyKind::Mac,         walk_ty);
 
     fn visit_item(&mut self, item: &'a Item) {
-        let parent_scope = &ParentScope {
-            module: self.current_module,
-            expansion: self.expansion,
-            legacy: self.current_legacy_scope,
-            derives: Vec::new(),
-        };
         let macro_use = match item.node {
             ItemKind::MacroDef(..) => {
-                self.current_legacy_scope = self.resolver.define_macro(item, parent_scope);
+                self.parent_scope.legacy = self.resolver.define_macro(item, &self.parent_scope);
                 return
             }
             ItemKind::Mac(..) => {
-                self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(item.id));
+                self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(item.id));
                 return
             }
             ItemKind::Mod(..) => self.contains_macro_use(&item.attrs),
             _ => false,
         };
 
-        let orig_current_module = self.current_module;
-        let orig_current_legacy_scope = self.current_legacy_scope;
-        self.build_reduced_graph_for_item(item, parent_scope);
+        let orig_current_module = self.parent_scope.module;
+        let orig_current_legacy_scope = self.parent_scope.legacy;
+        self.build_reduced_graph_for_item(item);
         visit::walk_item(self, item);
-        self.current_module = orig_current_module;
+        self.parent_scope.module = orig_current_module;
         if !macro_use {
-            self.current_legacy_scope = orig_current_legacy_scope;
+            self.parent_scope.legacy = orig_current_legacy_scope;
         }
     }
 
     fn visit_stmt(&mut self, stmt: &'a ast::Stmt) {
         if let ast::StmtKind::Mac(..) = stmt.node {
-            self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(stmt.id));
+            self.parent_scope.legacy = LegacyScope::Invocation(self.visit_invoc(stmt.id));
         } else {
             visit::walk_stmt(self, stmt);
         }
@@ -1031,21 +1020,21 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
             return;
         }
 
-        self.build_reduced_graph_for_foreign_item(foreign_item, self.expansion);
+        self.build_reduced_graph_for_foreign_item(foreign_item);
         visit::walk_foreign_item(self, foreign_item);
     }
 
     fn visit_block(&mut self, block: &'a Block) {
-        let orig_current_module = self.current_module;
-        let orig_current_legacy_scope = self.current_legacy_scope;
-        self.build_reduced_graph_for_block(block, self.expansion);
+        let orig_current_module = self.parent_scope.module;
+        let orig_current_legacy_scope = self.parent_scope.legacy;
+        self.build_reduced_graph_for_block(block);
         visit::walk_block(self, block);
-        self.current_module = orig_current_module;
-        self.current_legacy_scope = orig_current_legacy_scope;
+        self.parent_scope.module = orig_current_module;
+        self.parent_scope.legacy = orig_current_legacy_scope;
     }
 
     fn visit_trait_item(&mut self, item: &'a TraitItem) {
-        let parent = self.current_module;
+        let parent = self.parent_scope.module;
 
         if let TraitItemKind::Macro(_) = item.node {
             self.visit_invoc(item.id);
@@ -1067,11 +1056,12 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
         };
 
         let vis = ty::Visibility::Public;
-        self.resolver.define(parent, item.ident, ns, (res, vis, item.span, self.expansion));
+        let expansion = self.parent_scope.expansion;
+        self.resolver.define(parent, item.ident, ns, (res, vis, item.span, expansion));
 
-        self.current_module = parent.parent.unwrap(); // nearest normal ancestor
+        self.parent_scope.module = parent.parent.unwrap(); // nearest normal ancestor
         visit::walk_trait_item(self, item);
-        self.current_module = parent;
+        self.parent_scope.module = parent;
     }
 
     fn visit_token(&mut self, t: Token) {
@@ -1086,15 +1076,8 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {
 
     fn visit_attribute(&mut self, attr: &'a ast::Attribute) {
         if !attr.is_sugared_doc && is_builtin_attr(attr) {
-            let parent_scope = ParentScope {
-                module: self.current_module.nearest_item_scope(),
-                expansion: self.expansion,
-                legacy: self.current_legacy_scope,
-                // Let's hope discerning built-in attributes from derive helpers is not necessary
-                derives: Vec::new(),
-            };
-            parent_scope.module.builtin_attrs.borrow_mut().push((
-                attr.path.segments[0].ident, parent_scope
+            self.parent_scope.module.builtin_attrs.borrow_mut().push((
+                attr.path.segments[0].ident, self.parent_scope.clone()
             ));
         }
         visit::walk_attribute(self, attr);
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index e688857d038..efc02f1c057 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -72,7 +72,7 @@ struct LateResolutionVisitor<'a, 'b> {
     resolver: &'b mut Resolver<'a>,
 
     /// The module that represents the current item scope.
-    current_module: Module<'a>,
+    parent_scope: ParentScope<'a>,
 
     /// The current set of local scopes for types and values.
     /// FIXME #4948: Reuse ribs to avoid allocation.
@@ -290,10 +290,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
 
 impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b> {
+        // During late resolution we only track the module component of the parent scope,
+        // although it may be useful to track other components as well for diagnostics.
+        let parent_scope = resolver.dummy_parent_scope();
         let graph_root = resolver.graph_root;
         LateResolutionVisitor {
             resolver,
-            current_module: graph_root,
+            parent_scope,
             ribs: PerNS {
                 value_ns: vec![Rib::new(ModuleRibKind(graph_root))],
                 type_ns: vec![Rib::new(ModuleRibKind(graph_root))],
@@ -309,10 +312,6 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
     }
 
-    fn parent_scope(&self) -> ParentScope<'a> {
-        ParentScope { module: self.current_module, ..self.dummy_parent_scope() }
-    }
-
     fn resolve_ident_in_lexical_scope(&mut self,
                                       ident: Ident,
                                       ns: Namespace,
@@ -320,7 +319,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                       path_span: Span)
                                       -> Option<LexicalScopeBinding<'a>> {
         self.resolver.resolve_ident_in_lexical_scope(
-            ident, ns, &self.parent_scope(), record_used_id, path_span, &self.ribs[ns]
+            ident, ns, &self.parent_scope, record_used_id, path_span, &self.ribs[ns]
         )
     }
 
@@ -333,7 +332,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         crate_lint: CrateLint,
     ) -> PathResult<'a> {
         self.resolver.resolve_path_with_ribs(
-            path, opt_ns, &self.parent_scope(), record_used, path_span, crate_lint, &self.ribs
+            path, opt_ns, &self.parent_scope, record_used, path_span, crate_lint, &self.ribs
         )
     }
 
@@ -342,7 +341,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     // We maintain a list of value ribs and type ribs.
     //
     // Simultaneously, we keep track of the current position in the module
-    // graph in the `current_module` pointer. When we go to resolve a name in
+    // graph in the `parent_scope.module` pointer. When we go to resolve a name in
     // the value or type namespaces, we first look through all the ribs and
     // then query the module graph. When we resolve a name in the module
     // namespace, we can skip all the ribs (since nested modules are not
@@ -362,14 +361,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let module = self.module_map.get(&id).cloned(); // clones a reference
         if let Some(module) = module {
             // Move down in the graph.
-            let orig_module = replace(&mut self.current_module, module);
+            let orig_module = replace(&mut self.parent_scope.module, module);
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module)));
 
             self.finalize_current_module_macro_resolutions(module);
             let ret = f(self);
 
-            self.current_module = orig_module;
+            self.parent_scope.module = orig_module;
             self.ribs[ValueNS].pop();
             self.ribs[TypeNS].pop();
             ret
@@ -803,7 +802,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                                 debug!("resolve_implementation with_self_struct_ctor_rib");
                                 for impl_item in impl_items {
                                     this.resolver.resolve_visibility(
-                                        &impl_item.vis, &this.parent_scope()
+                                        &impl_item.vis, &this.parent_scope
                                     );
                                     // We also need a new scope for the impl item type parameters.
                                     let generic_params = HasGenericParams(&impl_item.generics,
@@ -879,12 +878,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         // If there is a TraitRef in scope for an impl, then the method must be in the
         // trait.
         if let Some((module, _)) = self.current_trait_ref {
-            let parent_scope = &self.parent_scope();
-            if self.resolve_ident_in_module(
+            if self.resolver.resolve_ident_in_module(
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
-                parent_scope,
+                &self.parent_scope,
                 false,
                 span,
             ).is_err() {
@@ -1024,7 +1022,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
     fn resolve_block(&mut self, block: &Block) {
         debug!("(resolving block) entering block");
         // Move down in the graph, if there's an anonymous module rooted here.
-        let orig_module = self.current_module;
+        let orig_module = self.parent_scope.module;
         let anonymous_module = self.block_map.get(&block.id).cloned(); // clones a reference
 
         let mut num_macro_definition_ribs = 0;
@@ -1032,7 +1030,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             debug!("(resolving block) found anonymous module, moving down");
             self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module)));
             self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module)));
-            self.current_module = anonymous_module;
+            self.parent_scope.module = anonymous_module;
             self.finalize_current_module_macro_resolutions(anonymous_module);
         } else {
             self.ribs[ValueNS].push(Rib::new(NormalRibKind));
@@ -1053,7 +1051,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
 
         // Move back up.
-        self.current_module = orig_module;
+        self.parent_scope.module = orig_module;
         for _ in 0 .. num_macro_definition_ribs {
             self.ribs[ValueNS].pop();
             self.label_ribs.pop();
@@ -1234,7 +1232,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 
         let report_errors = |this: &mut Self, res: Option<Res>| {
             let (err, candidates) = this.smart_resolve_report_errors(path, span, source, res);
-            let def_id = this.current_module.normal_ancestor_id;
+            let def_id = this.parent_scope.module.normal_ancestor_id;
             let node_id = this.definitions.as_local_node_id(def_id).unwrap();
             let better = res.is_some();
             this.use_injections.push(UseError { err, candidates, node_id, better });
@@ -1261,7 +1259,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                         if let Some((ctor_res, ctor_vis))
                                 = self.struct_constructors.get(&def_id).cloned() {
                             if is_expected(ctor_res) &&
-                               self.is_accessible_from(ctor_vis, self.current_module) {
+                               self.is_accessible_from(ctor_vis, self.parent_scope.module) {
                                 let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
                                 self.session.buffer_lint(lint, id, span,
                                     "private struct constructors are not usable through \
@@ -1360,9 +1358,9 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         if qself.is_none() {
             let path_seg = |seg: &Segment| PathSegment::from_ident(seg.ident);
             let path = Path { segments: path.iter().map(path_seg).collect(), span };
-            let parent_scope = &self.parent_scope();
-            if let Ok((_, res)) =
-                    self.resolve_macro_path(&path, None, parent_scope, false, false) {
+            if let Ok((_, res)) = self.resolver.resolve_macro_path(
+                &path, None, &self.parent_scope, false, false
+            ) {
                 return Some(PartialRes::new(res));
             }
         }
@@ -1693,12 +1691,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         let mut found_traits = Vec::new();
         // Look for the current trait.
         if let Some((module, _)) = self.current_trait_ref {
-            let parent_scope = &self.parent_scope();
-            if self.resolve_ident_in_module(
+            if self.resolver.resolve_ident_in_module(
                 ModuleOrUniformRoot::Module(module),
                 ident,
                 ns,
-                parent_scope,
+                &self.parent_scope,
                 false,
                 module.span,
             ).is_ok() {
@@ -1708,7 +1705,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
         }
 
         ident.span = ident.span.modern();
-        let mut search_module = self.current_module;
+        let mut search_module = self.parent_scope.module;
         loop {
             self.get_traits_in_module_containing_item(ident, ns, search_module, &mut found_traits);
             search_module = unwrap_or!(
@@ -1755,12 +1752,11 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
                 ).is_none() {
                     continue
                 }
-                let parent_scope = &self.parent_scope();
-                if self.resolve_ident_in_module_unadjusted(
+                if self.resolver.resolve_ident_in_module_unadjusted(
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     ns,
-                    parent_scope,
+                    &self.parent_scope,
                     false,
                     module.span,
                 ).is_ok() {
@@ -1796,7 +1792,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
 impl<'a> Resolver<'a> {
     pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) {
         let mut late_resolution_visitor = LateResolutionVisitor::new(self);
-        let module = late_resolution_visitor.current_module;
+        let module = late_resolution_visitor.parent_scope.module;
         late_resolution_visitor.finalize_current_module_macro_resolutions(module);
         visit::walk_crate(&mut late_resolution_visitor, krate);
         for (id, span) in late_resolution_visitor.unused_labels.iter() {
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index ed76111bd58..28ab53bc2f0 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -430,7 +430,8 @@ impl<'a> LateResolutionVisitor<'a, '_> {
             (Res::Def(DefKind::Struct, def_id), _) if ns == ValueNS => {
                 if let Some((ctor_def, ctor_vis))
                         = self.struct_constructors.get(&def_id).cloned() {
-                    let accessible_ctor = self.is_accessible_from(ctor_vis, self.current_module);
+                    let accessible_ctor =
+                        self.is_accessible_from(ctor_vis, self.parent_scope.module);
                     if is_expected(ctor_def) && !accessible_ctor {
                         err.span_label(
                             span,
@@ -505,12 +506,11 @@ impl<'a> LateResolutionVisitor<'a, '_> {
 
         // Look for associated items in the current trait.
         if let Some((module, _)) = self.current_trait_ref {
-            let parent_scope = &self.parent_scope();
-            if let Ok(binding) = self.resolve_ident_in_module(
+            if let Ok(binding) = self.resolver.resolve_ident_in_module(
                     ModuleOrUniformRoot::Module(module),
                     ident,
                     ns,
-                    parent_scope,
+                    &self.parent_scope,
                     false,
                     module.span,
                 ) {
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index cc89650bc29..914125b7cae 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -175,12 +175,15 @@ impl<'a> base::Resolver for Resolver<'a> {
         self.invocations.extend(derives.iter().map(|&derive| (derive, invocation)));
         let mut visitor = BuildReducedGraphVisitor {
             resolver: self,
-            current_module: invocation.module,
-            current_legacy_scope: invocation.parent_legacy_scope,
-            expansion: expn_id,
+            parent_scope: ParentScope {
+                module: invocation.module,
+                expansion: expn_id,
+                legacy: invocation.parent_legacy_scope,
+                derives: Vec::new(),
+            },
         };
         fragment.visit_with(&mut visitor);
-        invocation.output_legacy_scope.set(Some(visitor.current_legacy_scope));
+        invocation.output_legacy_scope.set(Some(visitor.parent_scope.legacy));
     }
 
     fn register_builtin_macro(&mut self, ident: ast::Ident, ext: SyntaxExtension) {