diff options
| -rw-r--r-- | src/librustc_resolve/build_reduced_graph.rs | 111 | ||||
| -rw-r--r-- | src/librustc_resolve/check_unused.rs | 4 | ||||
| -rw-r--r-- | src/librustc_resolve/diagnostics.rs | 30 | ||||
| -rw-r--r-- | src/librustc_resolve/lib.rs | 417 | ||||
| -rw-r--r-- | src/librustc_resolve/macros.rs | 61 | ||||
| -rw-r--r-- | src/librustc_resolve/resolve_imports.rs | 53 | ||||
| -rw-r--r-- | src/test/ui/hygiene/privacy-early.rs | 17 | ||||
| -rw-r--r-- | src/test/ui/hygiene/privacy-early.stderr | 21 | ||||
| -rw-r--r-- | src/test/ui/resolve/resolve-bad-visibility.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/resolve/resolve-bad-visibility.stderr | 21 | ||||
| -rw-r--r-- | src/test/ui/resolve/visibility-indeterminate.rs | 5 | ||||
| -rw-r--r-- | src/test/ui/resolve/visibility-indeterminate.stderr | 19 | ||||
| -rw-r--r-- | src/test/ui/span/visibility-ty-params.stderr | 14 |
13 files changed, 477 insertions, 300 deletions
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 9d01f330029..668daaba643 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -19,6 +19,7 @@ use rustc::middle::cstore::CrateStore; use rustc_metadata::cstore::LoadedMacro; use std::cell::Cell; +use std::ops::{Deref, DerefMut}; use std::ptr; use rustc_data_structures::sync::Lrc; @@ -115,7 +116,7 @@ impl<'a> Resolver<'a> { parent_prefix: &[Segment], nested: bool, // The whole `use` item - parent_scope: ParentScope<'a>, + parent_scope: &ParentScope<'a>, item: &Item, vis: ty::Visibility, root_span: Span, @@ -249,7 +250,7 @@ impl<'a> Resolver<'a> { root_span, item.id, vis, - parent_scope, + parent_scope.clone(), ); } ast::UseTreeKind::Glob => { @@ -266,7 +267,7 @@ impl<'a> Resolver<'a> { root_span, item.id, vis, - parent_scope, + parent_scope.clone(), ); } ast::UseTreeKind::Nested(ref items) => { @@ -297,7 +298,7 @@ impl<'a> Resolver<'a> { // This particular use tree tree, id, &prefix, true, // The whole `use` item - parent_scope.clone(), item, vis, root_span, + parent_scope, item, vis, root_span, ); } @@ -327,14 +328,16 @@ 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, parent_scope: &ParentScope<'a>) { let parent = parent_scope.module; let expansion = parent_scope.expansion; let ident = item.ident.gensym_if_underscore(); let sp = item.span; - let vis = self.resolve_visibility(&item.vis); + let vis = self.resolve_visibility(&item.vis, parent_scope); match item.node { ItemKind::Use(ref use_tree) => { @@ -361,7 +364,9 @@ impl<'a> Resolver<'a> { } else if orig_name == Some(kw::SelfLower) { self.graph_root } else { - let crate_id = self.crate_loader.process_extern_crate(item, &self.definitions); + let crate_id = self.resolver.crate_loader.process_extern_crate( + item, &self.resolver.definitions + ); self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX }) }; @@ -372,13 +377,13 @@ impl<'a> Resolver<'a> { } } - let used = self.process_legacy_macro_imports(item, module, &parent_scope); + let used = self.process_legacy_macro_imports(item, module, parent_scope); let binding = (module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas); let directive = self.arenas.alloc_import_directive(ImportDirective { root_id: item.id, id: item.id, - parent_scope, + parent_scope: parent_scope.clone(), imported_module: Cell::new(Some(ModuleOrUniformRoot::Module(module))), subclass: ImportDirectiveSubclass::ExternCrate { source: orig_name, @@ -395,7 +400,7 @@ impl<'a> Resolver<'a> { }); self.potentially_unused_imports.push(directive); let imported_binding = self.import(binding, directive); - if ptr::eq(self.current_module, self.graph_root) { + if ptr::eq(parent, self.graph_root) { if let Some(entry) = self.extern_prelude.get(&ident.modern()) { if expansion != ExpnId::root() && orig_name.is_some() && entry.extern_crate_item.is_none() { @@ -455,7 +460,7 @@ impl<'a> Resolver<'a> { // Functions introducing procedural macros reserve a slot // in the macro namespace as well (see #52225). - self.define_macro(item, expansion, &mut LegacyScope::Empty); + self.define_macro(item, parent_scope); } // These items live in the type namespace. @@ -511,8 +516,8 @@ impl<'a> Resolver<'a> { // Record field names for error reporting. let field_names = struct_def.fields().iter().filter_map(|field| { - let field_vis = self.resolve_visibility(&field.vis); - if ctor_vis.is_at_least(field_vis, &*self) { + let field_vis = self.resolve_visibility(&field.vis, parent_scope); + if ctor_vis.is_at_least(field_vis, &*self.resolver) { ctor_vis = field_vis; } field.ident.map(|ident| ident.name) @@ -538,7 +543,7 @@ impl<'a> Resolver<'a> { // Record field names for error reporting. let field_names = vdata.fields().iter().filter_map(|field| { - self.resolve_visibility(&field.vis); + self.resolve_visibility(&field.vis, parent_scope); field.ident.map(|ident| ident.name) }).collect(); let item_def_id = self.definitions.local_def_id(item.id); @@ -614,7 +619,13 @@ impl<'a> Resolver<'a> { ForeignItemKind::Macro(_) => unreachable!(), }; let parent = self.current_module; - let vis = self.resolve_visibility(&item.vis); + 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)); } @@ -630,7 +641,9 @@ impl<'a> Resolver<'a> { self.current_module = module; // Descend into the block. } } +} +impl<'a> Resolver<'a> { /// Builds the reduced graph for a single item in an external crate. fn build_reduced_graph_for_external_crate_res( &mut self, @@ -804,7 +817,9 @@ impl<'a> Resolver<'a> { self.session.struct_span_err(span, &msg).note(note).emit(); } } +} +impl<'a> BuildReducedGraphVisitor<'_, 'a> { /// Returns `true` if we should consider the underlying `extern crate` to be used. fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, parent_scope: &ParentScope<'a>) -> bool { @@ -873,7 +888,7 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(module), ident, MacroNS, - None, + parent_scope, false, ident.span, ); @@ -918,22 +933,36 @@ impl<'a> Resolver<'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, } +impl<'b> Deref for BuildReducedGraphVisitor<'_, 'b> { + type Target = Resolver<'b>; + fn deref(&self) -> &Self::Target { + self.resolver + } +} + +impl<'b> DerefMut for BuildReducedGraphVisitor<'_, 'b> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.resolver + } +} + 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.resolver.current_module.unresolved_invocations.borrow_mut().insert(invoc_id); + self.current_module.unresolved_invocations.borrow_mut().insert(invoc_id); - let invocation_data = self.resolver.arenas.alloc_invocation_data(InvocationData { - module: self.resolver.current_module, + let invocation_data = self.arenas.alloc_invocation_data(InvocationData { + module: self.current_module, parent_legacy_scope: self.current_legacy_scope, output_legacy_scope: Cell::new(None), }); - let old_invocation_data = self.resolver.invocations.insert(invoc_id, invocation_data); + let old_invocation_data = self.invocations.insert(invoc_id, invocation_data); assert!(old_invocation_data.is_none(), "invocation data is reset for an invocation"); invocation_data @@ -959,30 +988,30 @@ 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.resolver.define_macro(item, self.expansion, &mut self.current_legacy_scope); + self.current_legacy_scope = self.resolver.define_macro(item, parent_scope); return } ItemKind::Mac(..) => { self.current_legacy_scope = LegacyScope::Invocation(self.visit_invoc(item.id)); return } - ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs), + ItemKind::Mod(..) => self.contains_macro_use(&item.attrs), _ => false, }; - let orig_current_module = self.resolver.current_module; + let orig_current_module = self.current_module; let orig_current_legacy_scope = self.current_legacy_scope; - let parent_scope = ParentScope { - module: self.resolver.current_module, - expansion: self.expansion, - legacy: self.current_legacy_scope, - derives: Vec::new(), - }; - self.resolver.build_reduced_graph_for_item(item, parent_scope); + self.build_reduced_graph_for_item(item, parent_scope); visit::walk_item(self, item); - self.resolver.current_module = orig_current_module; + self.current_module = orig_current_module; if !macro_use { self.current_legacy_scope = orig_current_legacy_scope; } @@ -1002,21 +1031,21 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { return; } - self.resolver.build_reduced_graph_for_foreign_item(foreign_item, self.expansion); + self.build_reduced_graph_for_foreign_item(foreign_item, self.expansion); visit::walk_foreign_item(self, foreign_item); } fn visit_block(&mut self, block: &'a Block) { - let orig_current_module = self.resolver.current_module; + let orig_current_module = self.current_module; let orig_current_legacy_scope = self.current_legacy_scope; - self.resolver.build_reduced_graph_for_block(block, self.expansion); + self.build_reduced_graph_for_block(block, self.expansion); visit::walk_block(self, block); - self.resolver.current_module = orig_current_module; + self.current_module = orig_current_module; self.current_legacy_scope = orig_current_legacy_scope; } fn visit_trait_item(&mut self, item: &'a TraitItem) { - let parent = self.resolver.current_module; + let parent = self.current_module; if let TraitItemKind::Macro(_) = item.node { self.visit_invoc(item.id); @@ -1024,12 +1053,12 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { } // Add the item to the trait info. - let item_def_id = self.resolver.definitions.local_def_id(item.id); + let item_def_id = self.definitions.local_def_id(item.id); let (res, ns) = match item.node { TraitItemKind::Const(..) => (Res::Def(DefKind::AssocConst, item_def_id), ValueNS), TraitItemKind::Method(ref sig, _) => { if sig.decl.has_self() { - self.resolver.has_self.insert(item_def_id); + self.has_self.insert(item_def_id); } (Res::Def(DefKind::Method, item_def_id), ValueNS) } @@ -1040,9 +1069,9 @@ 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)); - self.resolver.current_module = parent.parent.unwrap(); // nearest normal ancestor + self.current_module = parent.parent.unwrap(); // nearest normal ancestor visit::walk_trait_item(self, item); - self.resolver.current_module = parent; + self.current_module = parent; } fn visit_token(&mut self, t: Token) { @@ -1058,7 +1087,7 @@ 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.resolver.current_module.nearest_item_scope(), + 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 diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 4fee15c59b3..d733a32c9c3 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -270,10 +270,6 @@ pub fn check_crate(resolver: &mut Resolver<'_>, krate: &ast::Crate) { } } - for (id, span) in resolver.unused_labels.iter() { - resolver.session.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label"); - } - let mut visitor = UnusedImportCheckVisitor { resolver, unused_imports: Default::default(), diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index aeb6f23da5a..c1fe7188f6d 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -18,7 +18,7 @@ use syntax_pos::{BytePos, Span}; use crate::resolve_imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; use crate::{is_self_type, is_self_value, path_names_to_string, KNOWN_TOOLS}; -use crate::{CrateLint, LegacyScope, Module, ModuleKind, ModuleOrUniformRoot}; +use crate::{CrateLint, LateResolutionVisitor, LegacyScope, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{PathResult, PathSource, ParentScope, Resolver, RibKind, Scope, ScopeSet, Segment}; type Res = def::Res<ast::NodeId>; @@ -78,7 +78,7 @@ fn add_module_candidates( } } -impl<'a> Resolver<'a> { +impl<'a> LateResolutionVisitor<'a, '_> { /// Handles error reporting for `smart_resolve_path_fragment` function. /// Creates base error and amends it with one short label and possibly some longer helps/notes. pub(crate) fn smart_resolve_report_errors( @@ -112,7 +112,7 @@ impl<'a> Resolver<'a> { (String::new(), "the crate root".to_string()) } else { let mod_path = &path[..path.len() - 1]; - let mod_prefix = match self.resolve_path_without_parent_scope( + let mod_prefix = match self.resolve_path( mod_path, Some(TypeNS), false, span, CrateLint::No ) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => @@ -288,7 +288,9 @@ impl<'a> Resolver<'a> { } (err, candidates) } +} +impl<'a> Resolver<'a> { fn followed_by_brace(&self, span: Span) -> (bool, Option<(Span, String)>) { // HACK(estebank): find a better way to figure out that this was a // parser issue where a struct literal is being used on an expression @@ -338,7 +340,9 @@ impl<'a> Resolver<'a> { } return (followed_by_brace, closing_brace) } +} +impl<'a> LateResolutionVisitor<'a, '_> { /// Provides context-dependent help for errors reported by the `smart_resolve_path_fragment` /// function. /// Returns `true` if able to provide context-dependent help. @@ -457,7 +461,7 @@ impl<'a> Resolver<'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(ctor_vis); + let accessible_ctor = self.is_accessible_from(ctor_vis, self.current_module); if is_expected(ctor_def) && !accessible_ctor { err.span_label( span, @@ -532,11 +536,12 @@ impl<'a> Resolver<'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( ModuleOrUniformRoot::Module(module), ident, ns, - None, + parent_scope, false, module.span, ) { @@ -553,7 +558,9 @@ impl<'a> Resolver<'a> { None } +} +impl<'a> Resolver<'a> { /// Lookup typo candidate in scope for a macro or import. fn early_lookup_typo_candidate( &mut self, @@ -569,9 +576,10 @@ impl<'a> Resolver<'a> { let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); if filter_fn(res) { for derive in &parent_scope.derives { - let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope }; + let parent_scope = + &ParentScope { derives: Vec::new(), ..*parent_scope }; if let Ok((Some(ext), _)) = this.resolve_macro_path( - derive, Some(MacroKind::Derive), &parent_scope, false, false + derive, Some(MacroKind::Derive), parent_scope, false, false ) { suggestions.extend(ext.helper_attrs.iter().map(|name| { TypoSuggestion::from_res(*name, res) @@ -682,7 +690,9 @@ impl<'a> Resolver<'a> { _ => None, } } +} +impl<'a> LateResolutionVisitor<'a, '_> { fn lookup_typo_candidate( &mut self, path: &[Segment], @@ -750,7 +760,7 @@ impl<'a> Resolver<'a> { } else { // Search in module. let mod_path = &path[..path.len() - 1]; - if let PathResult::Module(module) = self.resolve_path_without_parent_scope( + if let PathResult::Module(module) = self.resolve_path( mod_path, Some(TypeNS), false, span, CrateLint::No ) { if let ModuleOrUniformRoot::Module(module) = module { @@ -774,7 +784,9 @@ impl<'a> Resolver<'a> { _ => None, } } +} +impl<'a> Resolver<'a> { fn lookup_import_candidates_from_module<FilterFn>(&mut self, lookup_ident: Ident, namespace: Namespace, @@ -969,7 +981,7 @@ impl<'a> Resolver<'a> { ) { let is_expected = &|res: Res| res.macro_kind() == Some(macro_kind); let suggestion = self.early_lookup_typo_candidate( - ScopeSet::Macro(macro_kind), &parent_scope, ident, is_expected + ScopeSet::Macro(macro_kind), parent_scope, ident, is_expected ); add_typo_suggestion(err, suggestion, ident.span); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ce2bc79ff60..e11413fcda9 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -59,6 +59,7 @@ use log::debug; use std::cell::{Cell, RefCell}; use std::{cmp, fmt, iter, mem, ptr}; +use std::ops::{Deref, DerefMut}; use std::collections::BTreeSet; use std::mem::replace; use rustc_data_structures::ptr_key::PtrKey; @@ -537,35 +538,22 @@ enum PathSource<'a> { TupleStruct, // `m::A::B` in `<T as m::A>::B::C`. TraitItem(Namespace), - // Path in `pub(path)` - Visibility, } impl<'a> PathSource<'a> { fn namespace(self) -> Namespace { match self { - PathSource::Type | PathSource::Trait(_) | PathSource::Struct | - PathSource::Visibility => TypeNS, + PathSource::Type | PathSource::Trait(_) | PathSource::Struct => TypeNS, PathSource::Expr(..) | PathSource::Pat | PathSource::TupleStruct => ValueNS, PathSource::TraitItem(ns) => ns, } } - fn global_by_default(self) -> bool { - match self { - PathSource::Visibility => true, - PathSource::Type | PathSource::Expr(..) | PathSource::Pat | - PathSource::Struct | PathSource::TupleStruct | - PathSource::Trait(_) | PathSource::TraitItem(..) => false, - } - } - fn defer_to_typeck(self) -> bool { match self { PathSource::Type | PathSource::Expr(..) | PathSource::Pat | PathSource::Struct | PathSource::TupleStruct => true, - PathSource::Trait(_) | PathSource::TraitItem(..) | - PathSource::Visibility => false, + PathSource::Trait(_) | PathSource::TraitItem(..) => false, } } @@ -576,7 +564,6 @@ impl<'a> PathSource<'a> { PathSource::Pat => "unit struct/variant or constant", PathSource::Struct => "struct, variant or union type", PathSource::TupleStruct => "tuple struct/variant", - PathSource::Visibility => "module", PathSource::TraitItem(ns) => match ns { TypeNS => "associated type", ValueNS => "method or associated constant", @@ -655,10 +642,6 @@ impl<'a> PathSource<'a> { Res::Def(DefKind::AssocTy, _) if ns == TypeNS => true, _ => false, }, - PathSource::Visibility => match res { - Res::Def(DefKind::Mod, _) => true, - _ => false, - }, } } @@ -675,8 +658,6 @@ impl<'a> PathSource<'a> { __diagnostic_used!(E0574); __diagnostic_used!(E0575); __diagnostic_used!(E0576); - __diagnostic_used!(E0577); - __diagnostic_used!(E0578); match (self, has_unexpected_resolution) { (PathSource::Trait(_), true) => "E0404", (PathSource::Trait(_), false) => "E0405", @@ -690,8 +671,6 @@ impl<'a> PathSource<'a> { (PathSource::Pat, false) | (PathSource::TupleStruct, false) => "E0531", (PathSource::TraitItem(..), true) => "E0575", (PathSource::TraitItem(..), false) => "E0576", - (PathSource::Visibility, true) => "E0577", - (PathSource::Visibility, false) => "E0578", } } } @@ -801,8 +780,80 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { } } +struct LateResolutionVisitor<'a, 'b> { + resolver: &'b mut Resolver<'a>, + + /// The module that represents the current item scope. + current_module: Module<'a>, + + /// The current set of local scopes for types and values. + /// FIXME #4948: Reuse ribs to avoid allocation. + ribs: PerNS<Vec<Rib<'a>>>, + + /// The current set of local scopes, for labels. + label_ribs: Vec<Rib<'a, NodeId>>, + + /// The trait that the current context can refer to. + current_trait_ref: Option<(Module<'a>, TraitRef)>, + + /// The current trait's associated types' ident, used for diagnostic suggestions. + current_trait_assoc_types: Vec<Ident>, + + /// The current self type if inside an impl (used for better errors). + current_self_type: Option<Ty>, + + /// The current self item if inside an ADT (used for better errors). + current_self_item: Option<NodeId>, + + /// A list of labels as of yet unused. Labels will be removed from this map when + /// they are used (in a `break` or `continue` statement) + unused_labels: FxHashMap<NodeId, Span>, + + /// Only used for better errors on `fn(): fn()`. + current_type_ascription: Vec<Span>, +} + +impl<'a, 'b> LateResolutionVisitor<'a, '_> { + fn new(resolver: &'b mut Resolver<'a>) -> LateResolutionVisitor<'a, 'b> { + let graph_root = resolver.graph_root; + LateResolutionVisitor { + resolver, + current_module: graph_root, + ribs: PerNS { + value_ns: vec![Rib::new(ModuleRibKind(graph_root))], + type_ns: vec![Rib::new(ModuleRibKind(graph_root))], + macro_ns: vec![Rib::new(ModuleRibKind(graph_root))], + }, + label_ribs: Vec::new(), + current_trait_ref: None, + current_trait_assoc_types: Vec::new(), + current_self_type: None, + current_self_item: None, + unused_labels: Default::default(), + current_type_ascription: Vec::new(), + } + } + + fn parent_scope(&self) -> ParentScope<'a> { + ParentScope { module: self.current_module, ..self.dummy_parent_scope() } + } +} + +impl<'a> Deref for LateResolutionVisitor<'a, '_> { + type Target = Resolver<'a>; + fn deref(&self) -> &Self::Target { + self.resolver + } +} + +impl<'a> DerefMut for LateResolutionVisitor<'a, '_> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.resolver + } +} + /// Walks the whole crate in DFS order, visiting each item, resolving names as it goes. -impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { +impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> { fn visit_item(&mut self, item: &'tcx Item) { self.resolve_item(item); } @@ -1587,28 +1638,6 @@ pub struct Resolver<'a> { /// All non-determined imports. indeterminate_imports: Vec<&'a ImportDirective<'a>>, - /// The module that represents the current item scope. - current_module: Module<'a>, - - /// The current set of local scopes for types and values. - /// FIXME #4948: Reuse ribs to avoid allocation. - ribs: PerNS<Vec<Rib<'a>>>, - - /// The current set of local scopes, for labels. - label_ribs: Vec<Rib<'a, NodeId>>, - - /// The trait that the current context can refer to. - current_trait_ref: Option<(Module<'a>, TraitRef)>, - - /// The current trait's associated types' ident, used for diagnostic suggestions. - current_trait_assoc_types: Vec<Ident>, - - /// The current self type if inside an impl (used for better errors). - current_self_type: Option<Ty>, - - /// The current self item if inside an ADT (used for better errors). - current_self_item: Option<NodeId>, - /// FIXME: Refactor things so that these fields are passed through arguments and not resolver. /// We are resolving a last import segment during import validation. last_import_segment: bool, @@ -1655,10 +1684,6 @@ pub struct Resolver<'a> { pub maybe_unused_trait_imports: NodeSet, pub maybe_unused_extern_crates: Vec<(NodeId, Span)>, - /// A list of labels as of yet unused. Labels will be removed from this map when - /// they are used (in a `break` or `continue` statement) - pub unused_labels: FxHashMap<NodeId, Span>, - /// Privacy errors are delayed until the end in order to deduplicate them. privacy_errors: Vec<PrivacyError<'a>>, /// Ambiguity errors are delayed for deduplication. @@ -1703,9 +1728,6 @@ pub struct Resolver<'a> { /// it's not used during normal resolution, only for better error reporting. struct_constructors: DefIdMap<(Res, ty::Visibility)>, - /// Only used for better errors on `fn(): fn()`. - current_type_ascription: Vec<Span>, - injected_crate: Option<Module<'a>>, /// Features enabled for this crate. @@ -1872,8 +1894,8 @@ impl<'a> Resolver<'a> { let span = path.span; let path = Segment::from_path(&path); // FIXME(Manishearth): intra-doc links won't get warned of epoch changes. - match self.resolve_path_without_parent_scope(&path, Some(namespace), true, - span, CrateLint::No) { + let parent_scope = &self.dummy_parent_scope(); + match self.resolve_path(&path, Some(namespace), parent_scope, true, span, CrateLint::No) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => Ok(module.res().unwrap()), PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => @@ -1969,18 +1991,6 @@ impl<'a> Resolver<'a> { determined_imports: Vec::new(), indeterminate_imports: Vec::new(), - current_module: graph_root, - ribs: PerNS { - value_ns: vec![Rib::new(ModuleRibKind(graph_root))], - type_ns: vec![Rib::new(ModuleRibKind(graph_root))], - macro_ns: vec![Rib::new(ModuleRibKind(graph_root))], - }, - label_ribs: Vec::new(), - - current_trait_ref: None, - current_trait_assoc_types: Vec::new(), - current_self_type: None, - current_self_item: None, last_import_segment: false, blacklisted_binding: None, @@ -2002,8 +2012,6 @@ impl<'a> Resolver<'a> { maybe_unused_trait_imports: Default::default(), maybe_unused_extern_crates: Vec::new(), - unused_labels: FxHashMap::default(), - privacy_errors: Vec::new(), ambiguity_errors: Vec::new(), use_injections: Vec::new(), @@ -2036,7 +2044,6 @@ impl<'a> Resolver<'a> { unused_macros: Default::default(), proc_macro_stubs: Default::default(), special_derives: Default::default(), - current_type_ascription: Vec::new(), injected_crate: None, active_features: features.declared_lib_features.iter().map(|(feat, ..)| *feat) @@ -2089,10 +2096,13 @@ impl<'a> Resolver<'a> { /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { ImportResolver { resolver: self }.finalize_imports(); - self.current_module = self.graph_root; - self.finalize_current_module_macro_resolutions(); - visit::walk_crate(self, krate); + self.finalize_current_module_macro_resolutions(self.graph_root); + let mut late_resolution_visitor = LateResolutionVisitor::new(self); + visit::walk_crate(&mut late_resolution_visitor, krate); + for (id, span) in late_resolution_visitor.unused_labels.iter() { + self.session.buffer_lint(lint::builtin::UNUSED_LABELS, *id, *span, "unused label"); + } check_unused::check_crate(self, krate); self.report_errors(krate); @@ -2287,7 +2297,9 @@ impl<'a> Resolver<'a> { None } +} +impl<'a> Resolver<'a> { /// This resolves the identifier `ident` in the namespace `ns` in the current lexical scope. /// More specifically, we proceed up the hierarchy of scopes and return the binding for /// `ident` in the first scope that defines it (or None if no scopes define it). @@ -2308,8 +2320,10 @@ impl<'a> Resolver<'a> { fn resolve_ident_in_lexical_scope(&mut self, mut ident: Ident, ns: Namespace, + parent_scope: &ParentScope<'a>, record_used_id: Option<NodeId>, - path_span: Span) + path_span: Span, + ribs: &[Rib<'a>]) -> Option<LexicalScopeBinding<'a>> { assert!(ns == TypeNS || ns == ValueNS); if ident.name == kw::Invalid { @@ -2331,23 +2345,23 @@ impl<'a> Resolver<'a> { // Walk backwards up the ribs in scope. let record_used = record_used_id.is_some(); let mut module = self.graph_root; - for i in (0 .. self.ribs[ns].len()).rev() { - debug!("walk rib\n{:?}", self.ribs[ns][i].bindings); + for i in (0 .. ribs.len()).rev() { + debug!("walk rib\n{:?}", ribs[i].bindings); // Use the rib kind to determine whether we are resolving parameters // (modern hygiene) or local variables (legacy hygiene). - let rib_ident = if let AssocItemRibKind | ItemRibKind = self.ribs[ns][i].kind { + let rib_ident = if let AssocItemRibKind | ItemRibKind = ribs[i].kind { modern_ident } else { ident }; - if let Some(res) = self.ribs[ns][i].bindings.get(&rib_ident).cloned() { + if let Some(res) = ribs[i].bindings.get(&rib_ident).cloned() { // The ident resolves to a type parameter or local variable. return Some(LexicalScopeBinding::Res( - self.validate_res_from_ribs(ns, i, res, record_used, path_span), + self.validate_res_from_ribs(i, res, record_used, path_span, ribs), )); } - module = match self.ribs[ns][i].kind { + module = match ribs[i].kind { ModuleRibKind(module) => module, MacroDefinition(def) if def == self.macro_def(ident.span.ctxt()) => { // If an invocation of this macro created `ident`, give up on `ident` @@ -2358,10 +2372,12 @@ impl<'a> Resolver<'a> { _ => continue, }; + let item = self.resolve_ident_in_module_unadjusted( ModuleOrUniformRoot::Module(module), ident, ns, + parent_scope, record_used, path_span, ); @@ -2386,16 +2402,15 @@ impl<'a> Resolver<'a> { self.hygienic_lexical_parent(module, &mut ident.span) }; module = unwrap_or!(opt_module, break); - let orig_current_module = self.current_module; - self.current_module = module; // Lexical resolutions can never be a privacy error. + let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() }; let result = self.resolve_ident_in_module_unadjusted( ModuleOrUniformRoot::Module(module), ident, ns, + adjusted_parent_scope, record_used, path_span, ); - self.current_module = orig_current_module; match result { Ok(binding) => { @@ -2433,6 +2448,7 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(prelude), ident, ns, + parent_scope, false, path_span, ) { @@ -2498,7 +2514,7 @@ impl<'a> Resolver<'a> { module: ModuleOrUniformRoot<'a>, ident: Ident, ns: Namespace, - parent_scope: Option<&ParentScope<'a>>, + parent_scope: &ParentScope<'a>, record_used: bool, path_span: Span ) -> Result<&'a NameBinding<'a>, Determinacy> { @@ -2512,15 +2528,18 @@ impl<'a> Resolver<'a> { module: ModuleOrUniformRoot<'a>, mut ident: Ident, ns: Namespace, - parent_scope: Option<&ParentScope<'a>>, + parent_scope: &ParentScope<'a>, record_used: bool, path_span: Span ) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> { - let orig_current_module = self.current_module; + let tmp_parent_scope; + let mut adjusted_parent_scope = parent_scope; match module { - ModuleOrUniformRoot::Module(module) => { - if let Some(def) = ident.span.modernize_and_adjust(module.expansion) { - self.current_module = self.macro_def_scope(def); + 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() }; + adjusted_parent_scope = &tmp_parent_scope; } } ModuleOrUniformRoot::ExternPrelude => { @@ -2532,9 +2551,8 @@ impl<'a> Resolver<'a> { } } let result = self.resolve_ident_in_module_unadjusted_ext( - module, ident, ns, parent_scope, false, record_used, path_span, + module, ident, ns, adjusted_parent_scope, false, record_used, path_span, ); - self.current_module = orig_current_module; result } @@ -2587,7 +2605,9 @@ impl<'a> Resolver<'a> { } module } +} +impl<'a> LateResolutionVisitor<'a, '_> { // AST resolution // // We maintain a list of value ribs and type ribs. @@ -2606,8 +2626,32 @@ impl<'a> Resolver<'a> { // generate a fake "implementation scope" containing all the // implementations thus found, for compatibility with old resolve pass. + fn resolve_ident_in_lexical_scope(&mut self, + ident: Ident, + ns: Namespace, + record_used_id: Option<NodeId>, + 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] + ) + } + + fn resolve_path( + &mut self, + path: &[Segment], + opt_ns: Option<Namespace>, // `None` indicates a module path in import + record_used: bool, + path_span: Span, + 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 + ) + } + pub fn with_scope<F, T>(&mut self, id: NodeId, f: F) -> T - where F: FnOnce(&mut Resolver<'_>) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T { let id = self.definitions.local_def_id(id); let module = self.module_map.get(&id).cloned(); // clones a reference @@ -2617,7 +2661,7 @@ impl<'a> Resolver<'a> { self.ribs[ValueNS].push(Rib::new(ModuleRibKind(module))); self.ribs[TypeNS].push(Rib::new(ModuleRibKind(module))); - self.finalize_current_module_macro_resolutions(); + self.resolver.finalize_current_module_macro_resolutions(self.current_module); let ret = f(self); self.current_module = orig_module; @@ -2827,7 +2871,7 @@ impl<'a> Resolver<'a> { } fn with_generic_param_rib<'b, F>(&'b mut self, generic_params: GenericParameters<'a, 'b>, f: F) - where F: FnOnce(&mut Resolver<'_>) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) { debug!("with_generic_param_rib"); match generic_params { @@ -2901,7 +2945,7 @@ impl<'a> Resolver<'a> { } fn with_label_rib<F>(&mut self, f: F) - where F: FnOnce(&mut Resolver<'_>) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) { self.label_ribs.push(Rib::new(NormalRibKind)); f(self); @@ -2909,7 +2953,7 @@ impl<'a> Resolver<'a> { } fn with_item_rib<F>(&mut self, f: F) - where F: FnOnce(&mut Resolver<'_>) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) { self.ribs[ValueNS].push(Rib::new(ItemRibKind)); self.ribs[TypeNS].push(Rib::new(ItemRibKind)); @@ -2919,7 +2963,7 @@ impl<'a> Resolver<'a> { } fn with_constant_rib<F>(&mut self, f: F) - where F: FnOnce(&mut Resolver<'_>) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) { debug!("with_constant_rib"); self.ribs[ValueNS].push(Rib::new(ConstantItemRibKind)); @@ -2930,7 +2974,7 @@ impl<'a> Resolver<'a> { } fn with_current_self_type<T, F>(&mut self, self_type: &Ty, f: F) -> T - where F: FnOnce(&mut Resolver<'_>) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T { // Handle nested impls (inside fn bodies) let previous_value = replace(&mut self.current_self_type, Some(self_type.clone())); @@ -2940,7 +2984,7 @@ impl<'a> Resolver<'a> { } fn with_current_self_item<T, F>(&mut self, self_item: &Item, f: F) -> T - where F: FnOnce(&mut Resolver<'_>) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T { let previous_value = replace(&mut self.current_self_item, Some(self_item.id)); let result = f(self); @@ -2950,7 +2994,7 @@ impl<'a> Resolver<'a> { /// When evaluating a `trait` use its associated types' idents for suggestionsa in E0412. fn with_trait_items<T, F>(&mut self, trait_items: &Vec<TraitItem>, f: F) -> T - where F: FnOnce(&mut Resolver<'_>) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) -> T { let trait_assoc_types = replace( &mut self.current_trait_assoc_types, @@ -2966,7 +3010,7 @@ impl<'a> Resolver<'a> { /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`). fn with_optional_trait_ref<T, F>(&mut self, opt_trait_ref: Option<&TraitRef>, f: F) -> T - where F: FnOnce(&mut Resolver<'_>, Option<DefId>) -> T + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>, Option<DefId>) -> T { let mut new_val = None; let mut new_id = None; @@ -2984,7 +3028,7 @@ impl<'a> Resolver<'a> { new_id = Some(res.def_id()); let span = trait_ref.path.span; if let PathResult::Module(ModuleOrUniformRoot::Module(module)) = - self.resolve_path_without_parent_scope( + self.resolve_path( &path, Some(TypeNS), false, @@ -3003,7 +3047,7 @@ impl<'a> Resolver<'a> { } fn with_self_rib<F>(&mut self, self_res: Res, f: F) - where F: FnOnce(&mut Resolver<'_>) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) { let mut self_type_rib = Rib::new(NormalRibKind); @@ -3015,7 +3059,7 @@ impl<'a> Resolver<'a> { } fn with_self_struct_ctor_rib<F>(&mut self, impl_id: DefId, f: F) - where F: FnOnce(&mut Resolver<'_>) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) { let self_res = Res::SelfCtor(impl_id); let mut self_type_rib = Rib::new(NormalRibKind); @@ -3053,8 +3097,9 @@ impl<'a> Resolver<'a> { this.with_self_struct_ctor_rib(item_def_id, |this| { debug!("resolve_implementation with_self_struct_ctor_rib"); for impl_item in impl_items { - this.resolve_visibility(&impl_item.vis); - + this.resolver.resolve_visibility( + &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, AssocItemRibKind); @@ -3129,11 +3174,12 @@ impl<'a> Resolver<'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( ModuleOrUniformRoot::Module(module), ident, ns, - None, + parent_scope, false, span, ).is_err() { @@ -3282,7 +3328,7 @@ impl<'a> Resolver<'a> { self.ribs[ValueNS].push(Rib::new(ModuleRibKind(anonymous_module))); self.ribs[TypeNS].push(Rib::new(ModuleRibKind(anonymous_module))); self.current_module = anonymous_module; - self.finalize_current_module_macro_resolutions(); + self.resolver.finalize_current_module_macro_resolutions(self.current_module); } else { self.ribs[ValueNS].push(Rib::new(NormalRibKind)); } @@ -3497,7 +3543,6 @@ impl<'a> Resolver<'a> { ns, span, source.defer_to_typeck(), - source.global_by_default(), crate_lint, ) { Some(partial_res) if partial_res.unresolved_segments() == 0 => { @@ -3510,7 +3555,8 @@ impl<'a> Resolver<'a> { if let Res::Def(DefKind::Struct, def_id) = partial_res.base_res() { if let Some((ctor_res, ctor_vis)) = self.struct_constructors.get(&def_id).cloned() { - if is_expected(ctor_res) && self.is_accessible(ctor_vis) { + if is_expected(ctor_res) && + self.is_accessible_from(ctor_vis, self.current_module) { let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY; self.session.buffer_lint(lint, id, span, "private struct constructors are not usable through \ @@ -3540,8 +3586,7 @@ impl<'a> Resolver<'a> { let cl = CrateLint::No; let ns = Some(ns); if let PathResult::Module(_) | PathResult::NonModule(_) = - self.resolve_path_without_parent_scope(&std_path, ns, false, span, cl) - { + self.resolve_path(&std_path, ns, false, span, cl) { // check if we wrote `str::from_utf8` instead of `std::str::from_utf8` let item_span = path.iter().last().map(|segment| segment.ident.span) .unwrap_or(span); @@ -3678,13 +3723,12 @@ impl<'a> Resolver<'a> { primary_ns: Namespace, span: Span, defer_to_typeck: bool, - global_by_default: bool, crate_lint: CrateLint, ) -> Option<PartialRes> { let mut fin_res = None; for (i, ns) in [primary_ns, TypeNS, ValueNS].iter().cloned().enumerate() { if i == 0 || ns != primary_ns { - match self.resolve_qpath(id, qself, path, ns, span, global_by_default, crate_lint) { + match self.resolve_qpath(id, qself, path, ns, span, crate_lint) { // If defer_to_typeck, then resolution > no resolution, // otherwise full resolution > partial resolution > no resolution. Some(partial_res) if partial_res.unresolved_segments() == 0 || @@ -3700,10 +3744,9 @@ impl<'a> Resolver<'a> { if qself.is_none() { let path_seg = |seg: &Segment| ast::PathSegment::from_ident(seg.ident); let path = Path { segments: path.iter().map(path_seg).collect(), span }; - let parent_scope = - ParentScope { module: self.current_module, ..self.dummy_parent_scope() }; + let parent_scope = &self.parent_scope(); if let Ok((_, res)) = - self.resolve_macro_path(&path, None, &parent_scope, false, false) { + self.resolve_macro_path(&path, None, parent_scope, false, false) { return Some(PartialRes::new(res)); } } @@ -3719,18 +3762,15 @@ impl<'a> Resolver<'a> { path: &[Segment], ns: Namespace, span: Span, - global_by_default: bool, crate_lint: CrateLint, ) -> Option<PartialRes> { debug!( - "resolve_qpath(id={:?}, qself={:?}, path={:?}, \ - ns={:?}, span={:?}, global_by_default={:?})", + "resolve_qpath(id={:?}, qself={:?}, path={:?}, ns={:?}, span={:?})", id, qself, path, ns, span, - global_by_default, ); if let Some(qself) = qself { @@ -3779,13 +3819,7 @@ impl<'a> Resolver<'a> { )); } - let result = match self.resolve_path_without_parent_scope( - &path, - Some(ns), - true, - span, - crate_lint, - ) { + let result = match self.resolve_path(&path, Some(ns), true, span, crate_lint) { PathResult::NonModule(path_res) => path_res, PathResult::Module(ModuleOrUniformRoot::Module(module)) if !module.is_normal() => { PartialRes::new(module.res().unwrap()) @@ -3820,11 +3854,11 @@ impl<'a> Resolver<'a> { PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"), }; - if path.len() > 1 && !global_by_default && result.base_res() != Res::Err && + if path.len() > 1 && result.base_res() != Res::Err && path[0].ident.name != kw::PathRoot && path[0].ident.name != kw::DollarCrate { let unqualified_result = { - match self.resolve_path_without_parent_scope( + match self.resolve_path( &[*path.last().unwrap()], Some(ns), false, @@ -3845,23 +3879,24 @@ impl<'a> Resolver<'a> { Some(result) } +} - fn resolve_path_without_parent_scope( +impl<'a> Resolver<'a> { + fn resolve_path( &mut self, path: &[Segment], opt_ns: Option<Namespace>, // `None` indicates a module path in import + parent_scope: &ParentScope<'a>, record_used: bool, path_span: Span, crate_lint: CrateLint, ) -> PathResult<'a> { - // Macro and import paths must have full parent scope available during resolution, - // other paths will do okay with parent module alone. - assert!(opt_ns != None && opt_ns != Some(MacroNS)); - let parent_scope = ParentScope { module: self.current_module, ..self.dummy_parent_scope() }; - self.resolve_path(path, opt_ns, &parent_scope, record_used, path_span, crate_lint) + self.resolve_path_with_ribs( + path, opt_ns, parent_scope, record_used, path_span, crate_lint, &Default::default() + ) } - fn resolve_path( + fn resolve_path_with_ribs( &mut self, path: &[Segment], opt_ns: Option<Namespace>, // `None` indicates a module path in import @@ -3869,11 +3904,11 @@ impl<'a> Resolver<'a> { record_used: bool, path_span: Span, crate_lint: CrateLint, + ribs: &PerNS<Vec<Rib<'a>>>, ) -> PathResult<'a> { let mut module = None; let mut allow_super = true; let mut second_binding = None; - self.current_module = parent_scope.module; debug!( "resolve_path(path={:?}, opt_ns={:?}, record_used={:?}, \ @@ -3910,7 +3945,7 @@ impl<'a> Resolver<'a> { if allow_super && name == kw::Super { let mut ctxt = ident.span.ctxt().modern(); let self_module = match i { - 0 => Some(self.resolve_self(&mut ctxt, self.current_module)), + 0 => Some(self.resolve_self(&mut ctxt, parent_scope.module)), _ => match module { Some(ModuleOrUniformRoot::Module(module)) => Some(module), _ => None, @@ -3935,7 +3970,7 @@ impl<'a> Resolver<'a> { if name == kw::SelfLower { let mut ctxt = ident.span.ctxt().modern(); module = Some(ModuleOrUniformRoot::Module( - self.resolve_self(&mut ctxt, self.current_module))); + self.resolve_self(&mut ctxt, parent_scope.module))); continue; } if name == kw::PathRoot && ident.span.rust_2018() { @@ -3980,7 +4015,9 @@ impl<'a> Resolver<'a> { } let binding = if let Some(module) = module { - self.resolve_ident_in_module(module, ident, ns, None, record_used, path_span) + self.resolve_ident_in_module( + module, ident, ns, parent_scope, record_used, path_span + ) } else if opt_ns.is_none() || opt_ns == Some(MacroNS) { assert!(ns == TypeNS); let scopes = if opt_ns.is_none() { ScopeSet::Import(ns) } else { ScopeSet::Module }; @@ -3989,7 +4026,9 @@ impl<'a> Resolver<'a> { } else { let record_used_id = if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None }; - match self.resolve_ident_in_lexical_scope(ident, ns, record_used_id, path_span) { + match self.resolve_ident_in_lexical_scope( + ident, ns, parent_scope, record_used_id, path_span, &ribs[ns] + ) { // we found a locally-imported or available item/module Some(LexicalScopeBinding::Item(binding)) => Ok(binding), // we found a local variable or type param @@ -4176,17 +4215,17 @@ impl<'a> Resolver<'a> { // Validate a local resolution (from ribs). fn validate_res_from_ribs( &mut self, - ns: Namespace, rib_index: usize, res: Res, record_used: bool, span: Span, + all_ribs: &[Rib<'a>], ) -> Res { debug!("validate_res_from_ribs({:?})", res); - let ribs = &self.ribs[ns][rib_index + 1..]; + let ribs = &all_ribs[rib_index + 1..]; // An invalid forward use of a type parameter from a previous default. - if let ForwardTyParamBanRibKind = self.ribs[ns][rib_index].kind { + if let ForwardTyParamBanRibKind = all_ribs[rib_index].kind { if record_used { resolve_error(self, span, ResolutionError::ForwardDeclaredTyParam); } @@ -4195,7 +4234,7 @@ impl<'a> Resolver<'a> { } // An invalid use of a type parameter as the type of a const parameter. - if let TyParamAsConstParamTy = self.ribs[ns][rib_index].kind { + if let TyParamAsConstParamTy = all_ribs[rib_index].kind { if record_used { resolve_error(self, span, ResolutionError::ConstParamDependentOnTypeParam); } @@ -4288,9 +4327,11 @@ impl<'a> Resolver<'a> { } res } +} +impl<'a> LateResolutionVisitor<'a, '_> { fn with_resolved_label<F>(&mut self, label: Option<Label>, id: NodeId, f: F) - where F: FnOnce(&mut Resolver<'_>) + where F: FnOnce(&mut LateResolutionVisitor<'_, '_>) { if let Some(label) = label { self.unused_labels.insert(id, label.ident.span); @@ -4486,11 +4527,12 @@ impl<'a> Resolver<'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( ModuleOrUniformRoot::Module(module), ident, ns, - None, + parent_scope, false, module.span, ).is_ok() { @@ -4547,10 +4589,12 @@ impl<'a> Resolver<'a> { ).is_none() { continue } + let parent_scope = &self.parent_scope(); if self.resolve_ident_in_module_unadjusted( ModuleOrUniformRoot::Module(module), ident, ns, + parent_scope, false, module.span, ).is_ok() { @@ -4581,7 +4625,9 @@ impl<'a> Resolver<'a> { }; import_ids } +} +impl<'a> Resolver<'a> { fn record_partial_res(&mut self, node_id: NodeId, resolution: PartialRes) { debug!("(recording res) recording {:?} for {}", resolution, node_id); if let Some(prev_res) = self.partial_res_map.insert(node_id, resolution) { @@ -4589,14 +4635,16 @@ impl<'a> Resolver<'a> { } } - fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { + fn resolve_visibility( + &mut self, vis: &ast::Visibility, parent_scope: &ParentScope<'a> + ) -> ty::Visibility { match vis.node { ast::VisibilityKind::Public => ty::Visibility::Public, ast::VisibilityKind::Crate(..) => { ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) } ast::VisibilityKind::Inherited => { - ty::Visibility::Restricted(self.current_module.normal_ancestor_id) + ty::Visibility::Restricted(parent_scope.module.normal_ancestor_id) } ast::VisibilityKind::Restricted { ref path, id, .. } => { // For visibilities we are not ready to provide correct implementation of "uniform @@ -4626,23 +4674,58 @@ impl<'a> Resolver<'a> { let segments = crate_root.into_iter() .chain(path.segments.iter().map(|seg| seg.into())).collect::<Vec<_>>(); - let res = self.smart_resolve_path_fragment( - id, - None, + let expected_found_error = |this: &Self, res: Res| { + let path_str = Segment::names_to_string(&segments); + struct_span_err!(this.session, path.span, E0577, + "expected module, found {} `{}`", res.descr(), path_str) + .span_label(path.span, "not a module").emit(); + }; + match self.resolve_path( &segments, + Some(TypeNS), + parent_scope, + true, path.span, - PathSource::Visibility, CrateLint::SimplePath(id), - ).base_res(); - if res == Res::Err { - ty::Visibility::Public - } else { - let vis = ty::Visibility::Restricted(res.def_id()); - if self.is_accessible(vis) { - vis - } else { - self.session.span_err(path.span, "visibilities can only be restricted \ - to ancestor modules"); + ) { + PathResult::Module(ModuleOrUniformRoot::Module(module)) => { + let res = module.res().expect("visibility resolved to unnamed block"); + self.record_partial_res(id, PartialRes::new(res)); + if module.is_normal() { + if res == Res::Err { + ty::Visibility::Public + } else { + let vis = ty::Visibility::Restricted(res.def_id()); + if self.is_accessible_from(vis, parent_scope.module) { + vis + } else { + let msg = + "visibilities can only be restricted to ancestor modules"; + self.session.span_err(path.span, msg); + ty::Visibility::Public + } + } + } else { + expected_found_error(self, res); + ty::Visibility::Public + } + } + PathResult::Module(..) => { + self.session.span_err(path.span, "visibility must resolve to a module"); + ty::Visibility::Public + } + PathResult::NonModule(partial_res) => { + expected_found_error(self, partial_res.base_res()); + ty::Visibility::Public + } + PathResult::Failed { span, label, suggestion, .. } => { + let err = ResolutionError::FailedToResolve { label, suggestion }; + resolve_error(self, span, err); + ty::Visibility::Public + } + PathResult::Indeterminate => { + span_err!(self.session, path.span, E0578, + "cannot determine resolution for the visibility"); ty::Visibility::Public } } @@ -4650,10 +4733,6 @@ impl<'a> Resolver<'a> { } } - fn is_accessible(&self, vis: ty::Visibility) -> bool { - vis.is_accessible_from(self.current_module.normal_ancestor_id, self) - } - fn is_accessible_from(&self, vis: ty::Visibility, module: Module<'a>) -> bool { vis.is_accessible_from(module.normal_ancestor_id, self) } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 1f534bc41fe..cc89650bc29 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -166,9 +166,8 @@ impl<'a> base::Resolver for Resolver<'a> { fragment.visit_with(&mut DefCollector::new(&mut self.definitions, expn_id)); let invocation = self.invocations[&expn_id]; - self.current_module = invocation.module; - self.current_module.unresolved_invocations.borrow_mut().remove(&expn_id); - self.current_module.unresolved_invocations.borrow_mut().extend(derives); + 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); for &derive_invoc_id in derives { self.definitions.set_invocation_parent(derive_invoc_id, parent_def); @@ -176,6 +175,7 @@ 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, }; @@ -210,10 +210,10 @@ 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()); + 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) { + 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); @@ -227,8 +227,8 @@ impl<'a> base::Resolver for Resolver<'a> { } }; - let parent_scope = self.invoc_parent_scope(invoc_id, derives_in_scope); - let (ext, res) = self.smart_resolve_macro_path(path, kind, &parent_scope, force)?; + let parent_scope = &self.invoc_parent_scope(invoc_id, derives_in_scope); + let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); invoc.expansion_data.id.set_expn_info(ext.expn_info(span, fast_print_path(path))); @@ -471,9 +471,9 @@ impl<'a> Resolver<'a> { Scope::DeriveHelpers => { let mut result = Err(Determinacy::Determined); for derive in &parent_scope.derives { - let parent_scope = ParentScope { derives: Vec::new(), ..*parent_scope }; + let parent_scope = &ParentScope { derives: Vec::new(), ..*parent_scope }; match this.resolve_macro_path(derive, Some(MacroKind::Derive), - &parent_scope, true, force) { + parent_scope, true, force) { Ok((Some(ext), _)) => if ext.helper_attrs.contains(&ident.name) { let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), ty::Visibility::Public, derive.span, ExpnId::root()) @@ -502,7 +502,7 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(root_module), ident, ns, - None, + parent_scope, record_used, path_span, ); @@ -516,17 +516,16 @@ impl<'a> Resolver<'a> { } } Scope::Module(module) => { - let orig_current_module = mem::replace(&mut this.current_module, module); + let adjusted_parent_scope = &ParentScope { module, ..parent_scope.clone() }; let binding = this.resolve_ident_in_module_unadjusted_ext( ModuleOrUniformRoot::Module(module), ident, ns, - None, + adjusted_parent_scope, true, record_used, path_span, ); - this.current_module = orig_current_module; match binding { Ok(binding) => { let misc_flags = if ptr::eq(module, this.graph_root) { @@ -588,6 +587,7 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(prelude), ident, ns, + parent_scope, false, path_span, ) { @@ -710,9 +710,7 @@ impl<'a> Resolver<'a> { } } - pub fn finalize_current_module_macro_resolutions(&mut self) { - let module = self.current_module; - + pub fn finalize_current_module_macro_resolutions(&mut self, module: Module<'a>) { let check_consistency = |this: &mut Self, path: &[Segment], span, kind: MacroKind, initial_res: Option<Res>, res: Res| { if let Some(initial_res) = initial_res { @@ -753,8 +751,9 @@ impl<'a> Resolver<'a> { for (mut path, path_span, kind, parent_scope, initial_res) in macro_resolutions { // FIXME: Path resolution will ICE if segment IDs present. for seg in &mut path { seg.id = None; } - match self.resolve_path(&path, Some(MacroNS), &parent_scope, - true, path_span, CrateLint::No) { + match self.resolve_path( + &path, Some(MacroNS), &parent_scope, true, path_span, CrateLint::No + ) { PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => { let res = path_res.base_res(); check_consistency(self, &path, path_span, kind, initial_res, res); @@ -887,10 +886,10 @@ impl<'a> Resolver<'a> { Lrc::new(result) } - pub fn define_macro(&mut self, - item: &ast::Item, - expansion: ExpnId, - current_legacy_scope: &mut LegacyScope<'a>) { + pub fn define_macro( + &mut self, item: &ast::Item, parent_scope: &ParentScope<'a>, + ) -> LegacyScope<'a> { + let expansion = parent_scope.expansion; let (ext, ident, span, is_legacy) = match &item.node { ItemKind::MacroDef(def) => { let ext = self.compile_macro(item, self.session.edition()); @@ -901,7 +900,7 @@ impl<'a> Resolver<'a> { self.proc_macro_stubs.insert(item.id); (self.dummy_ext(macro_kind), ident, span, false) } - None => return, + None => return parent_scope.legacy, } _ => unreachable!(), }; @@ -909,7 +908,7 @@ impl<'a> Resolver<'a> { let def_id = self.definitions.local_def_id(item.id); let res = Res::Def(DefKind::Macro(ext.macro_kind()), def_id); self.macro_map.insert(def_id, ext); - self.local_macro_def_scopes.insert(item.id, self.current_module); + self.local_macro_def_scopes.insert(item.id, parent_scope.module); if is_legacy { let ident = ident.modern(); @@ -921,11 +920,7 @@ impl<'a> Resolver<'a> { ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX)) }; let binding = (res, vis, span, expansion).to_name_binding(self.arenas); - self.set_binding_parent_module(binding, self.current_module); - let legacy_binding = self.arenas.alloc_legacy_binding(LegacyBinding { - parent_legacy_scope: *current_legacy_scope, binding, ident - }); - *current_legacy_scope = LegacyScope::Binding(legacy_binding); + self.set_binding_parent_module(binding, parent_scope.module); self.all_macros.insert(ident.name, res); if is_macro_export { let module = self.graph_root; @@ -935,13 +930,17 @@ impl<'a> Resolver<'a> { self.check_reserved_macro_name(ident, res); self.unused_macros.insert(item.id, span); } + LegacyScope::Binding(self.arenas.alloc_legacy_binding(LegacyBinding { + parent_legacy_scope: parent_scope.legacy, binding, ident + })) } else { - let module = self.current_module; - let vis = self.resolve_visibility(&item.vis); + let module = parent_scope.module; + let vis = self.resolve_visibility(&item.vis, parent_scope); if vis != ty::Visibility::Public { self.unused_macros.insert(item.id, span); } self.define(module, ident, MacroNS, (res, vis, span, expansion)); + parent_scope.legacy } } } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 59438883d60..4611b813153 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -167,11 +167,12 @@ impl<'a> Resolver<'a> { module: ModuleOrUniformRoot<'a>, ident: Ident, ns: Namespace, + parent_scope: &ParentScope<'a>, record_used: bool, path_span: Span, ) -> Result<&'a NameBinding<'a>, Determinacy> { self.resolve_ident_in_module_unadjusted_ext( - module, ident, ns, None, false, record_used, path_span + module, ident, ns, parent_scope, false, record_used, path_span ).map_err(|(determinacy, _)| determinacy) } @@ -182,7 +183,7 @@ impl<'a> Resolver<'a> { module: ModuleOrUniformRoot<'a>, ident: Ident, ns: Namespace, - parent_scope: Option<&ParentScope<'a>>, + parent_scope: &ParentScope<'a>, restricted_shadowing: bool, record_used: bool, path_span: Span, @@ -191,9 +192,8 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(module) => module, ModuleOrUniformRoot::CrateRootAndExternPrelude => { assert!(!restricted_shadowing); - let parent_scope = self.dummy_parent_scope(); let binding = self.early_resolve_ident_in_lexical_scope( - ident, ScopeSet::AbsolutePath(ns), &parent_scope, + ident, ScopeSet::AbsolutePath(ns), parent_scope, record_used, record_used, path_span, ); return binding.map_err(|determinacy| (determinacy, Weak::No)); @@ -213,9 +213,6 @@ impl<'a> Resolver<'a> { } ModuleOrUniformRoot::CurrentScope => { assert!(!restricted_shadowing); - let parent_scope = - parent_scope.expect("no parent scope for a single-segment import"); - if ns == TypeNS { if ident.name == kw::Crate || ident.name == kw::DollarCrate { @@ -261,7 +258,8 @@ impl<'a> Resolver<'a> { } // `extern crate` are always usable for backwards compatibility, see issue #37020, // remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE`. - let usable = this.is_accessible(binding.vis) || binding.is_extern_crate(); + let usable = this.is_accessible_from(binding.vis, parent_scope.module) || + binding.is_extern_crate(); if usable { Ok(binding) } else { Err((Determined, Weak::No)) } }; @@ -299,7 +297,7 @@ impl<'a> Resolver<'a> { } } - if !self.is_accessible(binding.vis) && + if !self.is_accessible_from(binding.vis, parent_scope.module) && // Remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE` !(self.last_import_segment && binding.is_extern_crate()) { self.privacy_errors.push(PrivacyError(path_span, ident, binding)); @@ -322,7 +320,7 @@ impl<'a> Resolver<'a> { // Check if one of single imports can still define the name, // if it can then our result is not determined and can be invalidated. for single_import in &resolution.single_imports { - if !self.is_accessible(single_import.vis.get()) { + if !self.is_accessible_from(single_import.vis.get(), parent_scope.module) { continue; } let module = unwrap_or!(single_import.imported_module.get(), @@ -331,7 +329,7 @@ impl<'a> Resolver<'a> { SingleImport { source, .. } => source, _ => unreachable!(), }; - match self.resolve_ident_in_module(module, ident, ns, Some(&single_import.parent_scope), + match self.resolve_ident_in_module(module, ident, ns, &single_import.parent_scope, false, path_span) { Err(Determined) => continue, Ok(binding) if !self.is_accessible_from( @@ -379,7 +377,7 @@ impl<'a> Resolver<'a> { // Check if one of glob imports can still define the name, // if it can then our "no resolution" result is not determined and can be invalidated. for glob_import in module.globs.borrow().iter() { - if !self.is_accessible(glob_import.vis.get()) { + if !self.is_accessible_from(glob_import.vis.get(), parent_scope.module) { continue } let module = match glob_import.imported_module.get() { @@ -387,9 +385,14 @@ impl<'a> Resolver<'a> { Some(_) => continue, None => return Err((Undetermined, Weak::Yes)), }; - let (orig_current_module, mut ident) = (self.current_module, ident.modern()); + let tmp_parent_scope; + let (mut adjusted_parent_scope, mut ident) = (parent_scope, ident.modern()); match ident.span.glob_adjust(module.expansion, glob_import.span) { - Some(Some(def)) => self.current_module = self.macro_def_scope(def), + Some(Some(def)) => { + tmp_parent_scope = + ParentScope { module: self.macro_def_scope(def), ..parent_scope.clone() }; + adjusted_parent_scope = &tmp_parent_scope; + } Some(None) => {} None => continue, }; @@ -397,10 +400,10 @@ impl<'a> Resolver<'a> { ModuleOrUniformRoot::Module(module), ident, ns, + adjusted_parent_scope, false, path_span, ); - self.current_module = orig_current_module; match result { Err(Determined) => continue, @@ -798,11 +801,11 @@ impl<'a, 'b> ImportResolver<'a, 'b> { /// Attempts to resolve the given import, returning true if its resolution is determined. /// If successful, the resolved bindings are written into the module. fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { - debug!("(resolving import for module) resolving import `{}::...` in `{}`", - Segment::names_to_string(&directive.module_path), - module_to_string(self.current_module).unwrap_or_else(|| "???".to_string())); - - self.current_module = directive.parent_scope.module; + debug!( + "(resolving import for module) resolving import `{}::...` in `{}`", + Segment::names_to_string(&directive.module_path), + module_to_string(directive.parent_scope.module).unwrap_or_else(|| "???".to_string()), + ); let module = if let Some(module) = directive.imported_module.get() { module @@ -847,7 +850,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { // not define any names while resolving its module path. let orig_vis = directive.vis.replace(ty::Visibility::Invisible); let binding = this.resolve_ident_in_module( - module, source, ns, Some(&directive.parent_scope), false, directive.span + module, source, ns, &directive.parent_scope, false, directive.span ); directive.vis.set(orig_vis); @@ -892,8 +895,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> { &mut self, directive: &'b ImportDirective<'b> ) -> Option<UnresolvedImportError> { - self.current_module = directive.parent_scope.module; - let orig_vis = directive.vis.replace(ty::Visibility::Invisible); let prev_ambiguity_errors_len = self.ambiguity_errors.len(); let path_res = self.resolve_path(&directive.module_path, None, &directive.parent_scope, @@ -1019,7 +1020,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { mem::replace(&mut this.blacklisted_binding, target_bindings[ns].get()); let orig_last_import_segment = mem::replace(&mut this.last_import_segment, true); let binding = this.resolve_ident_in_module( - module, ident, ns, Some(&directive.parent_scope), true, directive.span + module, ident, ns, &directive.parent_scope, true, directive.span ); this.last_import_segment = orig_last_import_segment; this.blacklisted_binding = orig_blacklisted_binding; @@ -1070,7 +1071,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { let mut all_ns_failed = true; self.per_ns(|this, ns| if !type_ns_only || ns == TypeNS { let binding = this.resolve_ident_in_module( - module, ident, ns, Some(&directive.parent_scope), true, directive.span + module, ident, ns, &directive.parent_scope, true, directive.span ); if binding.is_ok() { all_ns_failed = false; @@ -1340,7 +1341,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { for ((mut ident, ns), binding) in bindings { let scope = match ident.span.reverse_glob_adjust(module.expansion, directive.span) { Some(Some(def)) => self.macro_def_scope(def), - Some(None) => self.current_module, + Some(None) => directive.parent_scope.module, None => continue, }; if self.is_accessible_from(binding.pseudo_vis(), scope) { diff --git a/src/test/ui/hygiene/privacy-early.rs b/src/test/ui/hygiene/privacy-early.rs new file mode 100644 index 00000000000..58fc74d65a5 --- /dev/null +++ b/src/test/ui/hygiene/privacy-early.rs @@ -0,0 +1,17 @@ +// edition:2018 + +#![feature(decl_macro)] + +mod foo { + fn f() {} + macro f() {} + + pub macro m() { + use f as g; //~ ERROR `f` is private, and cannot be re-exported + f!(); + } +} + +fn main() { + foo::m!(); +} diff --git a/src/test/ui/hygiene/privacy-early.stderr b/src/test/ui/hygiene/privacy-early.stderr new file mode 100644 index 00000000000..60e50e05fc3 --- /dev/null +++ b/src/test/ui/hygiene/privacy-early.stderr @@ -0,0 +1,21 @@ +error[E0364]: `f` is private, and cannot be re-exported + --> $DIR/privacy-early.rs:10:13 + | +LL | use f as g; + | ^^^^^^ +... +LL | foo::m!(); + | ---------- in this macro invocation + | +note: consider marking `f` as `pub` in the imported module + --> $DIR/privacy-early.rs:10:13 + | +LL | use f as g; + | ^^^^^^ +... +LL | foo::m!(); + | ---------- in this macro invocation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0364`. diff --git a/src/test/ui/resolve/resolve-bad-visibility.rs b/src/test/ui/resolve/resolve-bad-visibility.rs index d86c300c93f..7d48bb97b10 100644 --- a/src/test/ui/resolve/resolve-bad-visibility.rs +++ b/src/test/ui/resolve/resolve-bad-visibility.rs @@ -4,8 +4,8 @@ trait Tr {} pub(in E) struct S; //~ ERROR expected module, found enum `E` pub(in Tr) struct Z; //~ ERROR expected module, found trait `Tr` pub(in std::vec) struct F; //~ ERROR visibilities can only be restricted to ancestor modules -pub(in nonexistent) struct G; //~ ERROR cannot find module `nonexistent` in the crate root -pub(in too_soon) struct H; //~ ERROR cannot find module `too_soon` in the crate root +pub(in nonexistent) struct G; //~ ERROR failed to resolve +pub(in too_soon) struct H; //~ ERROR failed to resolve // Visibilities are resolved eagerly without waiting for modules becoming fully populated. // Visibilities can only use ancestor modules legally which are always available in time, diff --git a/src/test/ui/resolve/resolve-bad-visibility.stderr b/src/test/ui/resolve/resolve-bad-visibility.stderr index b8004a48a67..a133b02335c 100644 --- a/src/test/ui/resolve/resolve-bad-visibility.stderr +++ b/src/test/ui/resolve/resolve-bad-visibility.stderr @@ -1,9 +1,3 @@ -error: visibilities can only be restricted to ancestor modules - --> $DIR/resolve-bad-visibility.rs:6:8 - | -LL | pub(in std::vec) struct F; - | ^^^^^^^^ - error[E0577]: expected module, found enum `E` --> $DIR/resolve-bad-visibility.rs:4:8 | @@ -16,17 +10,24 @@ error[E0577]: expected module, found trait `Tr` LL | pub(in Tr) struct Z; | ^^ not a module -error[E0578]: cannot find module `nonexistent` in the crate root +error: visibilities can only be restricted to ancestor modules + --> $DIR/resolve-bad-visibility.rs:6:8 + | +LL | pub(in std::vec) struct F; + | ^^^^^^^^ + +error[E0433]: failed to resolve: maybe a missing `extern crate nonexistent;`? --> $DIR/resolve-bad-visibility.rs:7:8 | LL | pub(in nonexistent) struct G; - | ^^^^^^^^^^^ not found in the crate root + | ^^^^^^^^^^^ maybe a missing `extern crate nonexistent;`? -error[E0578]: cannot find module `too_soon` in the crate root +error[E0433]: failed to resolve: maybe a missing `extern crate too_soon;`? --> $DIR/resolve-bad-visibility.rs:8:8 | LL | pub(in too_soon) struct H; - | ^^^^^^^^ not found in the crate root + | ^^^^^^^^ maybe a missing `extern crate too_soon;`? error: aborting due to 5 previous errors +For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/resolve/visibility-indeterminate.rs b/src/test/ui/resolve/visibility-indeterminate.rs new file mode 100644 index 00000000000..595eaf440c9 --- /dev/null +++ b/src/test/ui/resolve/visibility-indeterminate.rs @@ -0,0 +1,5 @@ +// edition:2018 + +foo!(); //~ ERROR cannot find macro `foo!` in this scope + +pub(in ::bar) struct Baz {} //~ ERROR cannot determine resolution for the visibility diff --git a/src/test/ui/resolve/visibility-indeterminate.stderr b/src/test/ui/resolve/visibility-indeterminate.stderr new file mode 100644 index 00000000000..a259c8090b3 --- /dev/null +++ b/src/test/ui/resolve/visibility-indeterminate.stderr @@ -0,0 +1,19 @@ +error[E0578]: cannot determine resolution for the visibility + --> $DIR/visibility-indeterminate.rs:5:8 + | +LL | pub(in ::bar) struct Baz {} + | ^^^^^ + +error: cannot find macro `foo!` in this scope + --> $DIR/visibility-indeterminate.rs:3:1 + | +LL | foo!(); + | ^^^ + +error[E0601]: `main` function not found in crate `visibility_indeterminate` + | + = note: consider adding a `main` function to `$DIR/visibility-indeterminate.rs` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/span/visibility-ty-params.stderr b/src/test/ui/span/visibility-ty-params.stderr index cdbede3c197..c2f0711b0c8 100644 --- a/src/test/ui/span/visibility-ty-params.stderr +++ b/src/test/ui/span/visibility-ty-params.stderr @@ -4,19 +4,17 @@ error: unexpected generic arguments in path LL | m!{ S<u8> } | ^^^^^ +error[E0577]: expected module, found struct `S` + --> $DIR/visibility-ty-params.rs:6:5 + | +LL | m!{ S<u8> } + | ^^^^^ not a module + error: unexpected generic arguments in path --> $DIR/visibility-ty-params.rs:10:9 | LL | m!{ m<> } | ^^^ -error[E0577]: expected module, found struct `S` - --> $DIR/visibility-ty-params.rs:6:5 - | -LL | m!{ S<u8> } - | -^^^^ - | | - | help: a module with a similar name exists: `m` - error: aborting due to 3 previous errors |
