diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-08-08 03:44:16 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2019-08-10 13:16:06 +0300 |
| commit | df03e420e020c2ccc71bad4f7978b49a1c049435 (patch) | |
| tree | f0b2ad3399cdb9b069b6124531d528c13ca0fa9a | |
| parent | ff85d1c2d28e19797b9d9aa67bbdfaf92e015c57 (diff) | |
| download | rust-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.rs | 97 | ||||
| -rw-r--r-- | src/librustc_resolve/late.rs | 58 | ||||
| -rw-r--r-- | src/librustc_resolve/late/diagnostics.rs | 8 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 11 |
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) { |
