diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index a437f86e37789..3f6f27ce6a30c 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1052,9 +1052,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } } - Scope::Module(module, _) => { + Scope::NonGlobModule(module, _) => { this.add_module_candidates(module, suggestions, filter_fn, None); } + Scope::GlobModule(..) => { + // already inserted in `Scope::NonGlobModule` arm + } Scope::MacroUsePrelude => { suggestions.extend(this.macro_use_prelude.iter().filter_map( |(name, binding)| { @@ -1476,9 +1479,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { &parent_scope, ident.span.ctxt(), |this, scope, _use_prelude, _ctxt| { - let Scope::Module(m, _) = scope else { + let (Scope::NonGlobModule(m, _) | Scope::GlobModule(m, _)) = scope else { return None; }; + for (_, resolution) in this.resolutions(m).borrow().iter() { let Some(binding) = resolution.borrow().best_binding() else { continue; diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index c1b3aff4e69f6..b12f8cc71ecdf 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -40,6 +40,18 @@ enum Shadowing { Unrestricted, } +bitflags::bitflags! { + #[derive(Clone, Copy, Debug)] + struct Flags: u8 { + const MACRO_RULES = 1 << 0; + const NON_GLOB_MODULE = 1 << 1; + const GLOB_MODULE = 1 << 2; + const MISC_SUGGEST_CRATE = 1 << 3; + const MISC_SUGGEST_SELF = 1 << 4; + const MISC_FROM_PRELUDE = 1 << 5; + } +} + impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// A generic scope visitor. /// Visits scopes in order to resolve some identifier in them or perform other actions. @@ -101,22 +113,27 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let (ns, macro_kind) = match scope_set { ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) + | ScopeSet::Module(ns, ..) | ScopeSet::Late(ns, ..) => (ns, None), ScopeSet::ExternPrelude => (TypeNS, None), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), }; let module = match scope_set { // Start with the specified module. - ScopeSet::Late(_, module, _) | ScopeSet::ModuleAndExternPrelude(_, module) => module, + ScopeSet::Late(_, module, _) + | ScopeSet::ModuleAndExternPrelude(_, module) + | ScopeSet::Module(_, module) => module, // Jump out of trait or enum modules, they do not act as scopes. _ => parent_scope.module.nearest_item_scope(), }; + + let module_scope = matches!(scope_set, ScopeSet::Module(..)); let module_and_extern_prelude = matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)); let extern_prelude = matches!(scope_set, ScopeSet::ExternPrelude); let mut scope = match ns { - _ if module_and_extern_prelude => Scope::Module(module, None), + _ if module_and_extern_prelude || module_scope => Scope::NonGlobModule(module, None), _ if extern_prelude => Scope::ExternPreludeItems, - TypeNS | ValueNS => Scope::Module(module, None), + TypeNS | ValueNS => Scope::NonGlobModule(module, None), MacroNS => Scope::DeriveHelpers(parent_scope.expansion), }; let mut ctxt = ctxt.normalize_to_macros_2_0(); @@ -143,7 +160,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } true } - Scope::Module(..) => true, + Scope::NonGlobModule(..) | Scope::GlobModule(..) => true, Scope::MacroUsePrelude => use_prelude || rust_2015, Scope::BuiltinAttrs => true, Scope::ExternPreludeItems | Scope::ExternPreludeFlags => { @@ -182,16 +199,21 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { MacroRulesScope::Invocation(invoc_id) => { Scope::MacroRules(self.invocation_parent_scopes[&invoc_id].macro_rules) } - MacroRulesScope::Empty => Scope::Module(module, None), + MacroRulesScope::Empty => Scope::NonGlobModule(module, None), }, - Scope::Module(..) if module_and_extern_prelude => match ns { + Scope::GlobModule(..) if module_and_extern_prelude => match ns { TypeNS => { ctxt.adjust(ExpnId::root()); Scope::ExternPreludeItems } ValueNS | MacroNS => break, }, - Scope::Module(module, prev_lint_id) => { + Scope::GlobModule(..) if module_scope => break, + Scope::NonGlobModule(module, prev_lint_id) => { + use_prelude = !module.no_implicit_prelude; + Scope::GlobModule(module, prev_lint_id) + } + Scope::GlobModule(module, prev_lint_id) => { use_prelude = !module.no_implicit_prelude; let derive_fallback_lint_id = match scope_set { ScopeSet::Late(.., lint_id) => lint_id, @@ -199,7 +221,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }; match self.hygienic_lexical_parent(module, &mut ctxt, derive_fallback_lint_id) { Some((parent_module, lint_id)) => { - Scope::Module(parent_module, lint_id.or(prev_lint_id)) + Scope::NonGlobModule(parent_module, lint_id.or(prev_lint_id)) } None => { ctxt.adjust(ExpnId::root()); @@ -339,7 +361,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, ns, parent_scope, - Shadowing::Unrestricted, finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), ignore_binding, None, @@ -392,17 +413,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_binding: Option>, ignore_import: Option>, ) -> Result, Determinacy> { - bitflags::bitflags! { - #[derive(Clone, Copy)] - struct Flags: u8 { - const MACRO_RULES = 1 << 0; - const MODULE = 1 << 1; - const MISC_SUGGEST_CRATE = 1 << 2; - const MISC_SUGGEST_SELF = 1 << 3; - const MISC_FROM_PRELUDE = 1 << 4; - } - } - assert!(force || finalize.is_none()); // `finalize` implies `force` // Make sure `self`, `super` etc produce an error when passed to here. @@ -413,6 +423,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let (ns, macro_kind) = match scope_set { ScopeSet::All(ns) | ScopeSet::ModuleAndExternPrelude(ns, _) + | ScopeSet::Module(ns, ..) | ScopeSet::Late(ns, ..) => (ns, None), ScopeSet::ExternPrelude => (TypeNS, None), ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind)), @@ -494,10 +505,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { MacroRulesScope::Invocation(_) => Err(Determinacy::Undetermined), _ => Err(Determinacy::Determined), }, - Scope::Module(module, derive_fallback_lint_id) => { + Scope::NonGlobModule(module, derive_fallback_lint_id) => { // FIXME: use `finalize_scope` here. let (adjusted_parent_scope, adjusted_finalize) = - if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) { + if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) + || matches!(scope_set, ScopeSet::Module(..)) + { (parent_scope, finalize) } else { ( @@ -505,20 +518,87 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.map(|f| Finalize { used: Used::Scope, ..f }), ) }; - let binding = this.reborrow().resolve_ident_in_module_unadjusted( - ModuleOrUniformRoot::Module(module), + + let binding = this.reborrow().resolve_ident_in_non_glob_module_unadjusted( + module, ident, ns, adjusted_parent_scope, - if matches!(scope_set, ScopeSet::Late(..)) { - Shadowing::Unrestricted - } else { - Shadowing::Restricted + match scope_set { + ScopeSet::Late(..) | ScopeSet::Module(..) => { + Shadowing::Unrestricted + } + _ => Shadowing::Restricted, }, adjusted_finalize, ignore_binding, + ); + + match binding { + Ok(binding) => { + if let Some(lint_id) = derive_fallback_lint_id { + this.get_mut().lint_buffer.buffer_lint( + PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, + lint_id, + orig_ident.span, + BuiltinLintDiag::ProcMacroDeriveResolutionFallback { + span: orig_ident.span, + ns, + ident, + }, + ); + } + + let misc_flags = this.create_module_misc_flags(module); + Ok((binding, Flags::NON_GLOB_MODULE | misc_flags)) + } + Err((Determinacy::Undetermined, Weak::No)) => { + return Some(Err(Determinacy::determined(force))); + } + Err((Determinacy::Undetermined, Weak::Yes)) => { + Err(Determinacy::Undetermined) + } + Err((Determinacy::Determined, weak)) => { + // Only go through Glob Scope with `Weak::Yes` errors in ScopeSet::Module + if matches!(scope_set, ScopeSet::Module(..)) + && matches!(weak, Weak::No) + { + return Some(Err(Determinacy::Determined)); + } + + Err(Determinacy::Determined) + } + } + } + Scope::GlobModule(module, derive_fallback_lint_id) => { + let (adjusted_parent_scope, finalize) = + if matches!(scope_set, ScopeSet::ModuleAndExternPrelude(..)) + || matches!(scope_set, ScopeSet::Module(..)) + { + (parent_scope, finalize) + } else { + ( + &ParentScope { module, ..*parent_scope }, + finalize.map(|f| Finalize { used: Used::Scope, ..f }), + ) + }; + + let binding = this.reborrow().resolve_ident_in_glob_module_unadjusted( + module, + ident, + ns, + adjusted_parent_scope, + match scope_set { + ScopeSet::Late(..) | ScopeSet::Module(..) => { + Shadowing::Unrestricted + } + _ => Shadowing::Restricted, + }, + finalize.map(|finalize| Finalize { used: Used::Scope, ..finalize }), + ignore_binding, ignore_import, ); + match binding { Ok(binding) => { if let Some(lint_id) = derive_fallback_lint_id { @@ -533,14 +613,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { }, ); } - let misc_flags = if module == this.graph_root { - Flags::MISC_SUGGEST_CRATE - } else if module.is_normal() { - Flags::MISC_SUGGEST_SELF - } else { - Flags::empty() - }; - Ok((binding, Flags::MODULE | misc_flags)) + + let misc_flags = this.create_module_misc_flags(module); + Ok((binding, Flags::GLOB_MODULE | misc_flags)) } Err((Determinacy::Undetermined, Weak::No)) => { return Some(Err(Determinacy::determined(force))); @@ -590,7 +665,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, ns, parent_scope, - Shadowing::Unrestricted, None, ignore_binding, ignore_import, @@ -650,6 +724,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some((innermost_binding, innermost_flags)) = innermost_result { // Found another solution, if the first one was "weak", report an error. let (res, innermost_res) = (binding.res(), innermost_binding.res()); + if res != innermost_res { let is_builtin = |res| { matches!(res, Res::NonMacroAttr(NonMacroAttrKind::Builtin(..))) @@ -668,13 +743,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { { Some(AmbiguityKind::DeriveHelper) } else if innermost_flags.contains(Flags::MACRO_RULES) - && flags.contains(Flags::MODULE) + && (flags.contains(Flags::NON_GLOB_MODULE) + || flags.contains(Flags::GLOB_MODULE)) && !this.disambiguate_macro_rules_vs_modularized( innermost_binding, binding, ) || flags.contains(Flags::MACRO_RULES) - && innermost_flags.contains(Flags::MODULE) + && (innermost_flags.contains(Flags::NON_GLOB_MODULE) + || innermost_flags.contains(Flags::GLOB_MODULE)) && !this.disambiguate_macro_rules_vs_modularized( binding, innermost_binding, @@ -720,7 +797,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } Err(Determinacy::Determined) => {} - Err(Determinacy::Undetermined) => determinacy = Determinacy::Undetermined, + Err(Determinacy::Undetermined) => { + if let Scope::NonGlobModule(..) = scope { + // we wait for Scope::GlobModule to determine `determinacy` + } else { + determinacy = Determinacy::Undetermined; + } + } } None @@ -739,6 +822,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { Err(Determinacy::determined(determinacy == Determinacy::Determined || force)) } + fn create_module_misc_flags(&self, module: Module<'ra>) -> Flags { + if module == self.graph_root { + Flags::MISC_SUGGEST_CRATE + } else if module.is_normal() { + Flags::MISC_SUGGEST_SELF + } else { + Flags::empty() + } + } + #[instrument(level = "debug", skip(self))] pub(crate) fn maybe_resolve_ident_in_module<'r>( self: CmResolver<'r, 'ra, 'tcx>, @@ -749,7 +842,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_import: Option>, ) -> Result, Determinacy> { self.resolve_ident_in_module(module, ident, ns, parent_scope, None, None, ignore_import) - .map_err(|(determinacy, _)| determinacy) } #[instrument(level = "debug", skip(self))] @@ -762,7 +854,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize: Option, ignore_binding: Option>, ignore_import: Option>, - ) -> Result, (Determinacy, Weak)> { + ) -> Result, Determinacy> { let tmp_parent_scope; let mut adjusted_parent_scope = parent_scope; match module { @@ -785,7 +877,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, ns, adjusted_parent_scope, - Shadowing::Unrestricted, finalize, ignore_binding, ignore_import, @@ -795,23 +886,29 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { /// Invariant: if `finalize` is `Some`, expansion and import resolution must be complete. #[instrument(level = "debug", skip(self))] fn resolve_ident_in_module_unadjusted<'r>( - mut self: CmResolver<'r, 'ra, 'tcx>, + self: CmResolver<'r, 'ra, 'tcx>, module: ModuleOrUniformRoot<'ra>, ident: Ident, ns: Namespace, parent_scope: &ParentScope<'ra>, - shadowing: Shadowing, finalize: Option, // This binding should be ignored during in-module resolution, so that we don't get // "self-confirming" import resolutions during import validation and checking. ignore_binding: Option>, ignore_import: Option>, - ) -> Result, (Determinacy, Weak)> { - let module = match module { - ModuleOrUniformRoot::Module(module) => module, - ModuleOrUniformRoot::ModuleAndExternPrelude(module) => { - assert_eq!(shadowing, Shadowing::Unrestricted); - let binding = self.early_resolve_ident_in_lexical_scope( + ) -> Result, Determinacy> { + match module { + ModuleOrUniformRoot::Module(module) => self.early_resolve_ident_in_lexical_scope( + ident, + ScopeSet::Module(ns, module), + parent_scope, + finalize, + finalize.is_some(), + ignore_binding, + ignore_import, + ), + ModuleOrUniformRoot::ModuleAndExternPrelude(module) => self + .early_resolve_ident_in_lexical_scope( ident, ScopeSet::ModuleAndExternPrelude(ns, module), parent_scope, @@ -819,15 +916,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.is_some(), ignore_binding, ignore_import, - ); - return binding.map_err(|determinacy| (determinacy, Weak::No)); - } + ), ModuleOrUniformRoot::ExternPrelude => { - assert_eq!(shadowing, Shadowing::Unrestricted); return if ns != TypeNS { - Err((Determined, Weak::No)) + Err(Determined) } else { - let binding = self.early_resolve_ident_in_lexical_scope( + self.early_resolve_ident_in_lexical_scope( ident, ScopeSet::ExternPrelude, parent_scope, @@ -835,12 +929,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.is_some(), ignore_binding, ignore_import, - ); - return binding.map_err(|determinacy| (determinacy, Weak::No)); + ) }; } ModuleOrUniformRoot::CurrentScope => { - assert_eq!(shadowing, Shadowing::Unrestricted); if ns == TypeNS { if ident.name == kw::Crate || ident.name == kw::DollarCrate { let module = self.resolve_crate_root(ident); @@ -852,7 +944,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } } - let binding = self.early_resolve_ident_in_lexical_scope( + self.early_resolve_ident_in_lexical_scope( ident, ScopeSet::All(ns), parent_scope, @@ -860,11 +952,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { finalize.is_some(), ignore_binding, ignore_import, - ); - return binding.map_err(|determinacy| (determinacy, Weak::No)); + ) } - }; + } + } + fn resolve_ident_in_non_glob_module_unadjusted<'r>( + mut self: CmResolver<'r, 'ra, 'tcx>, + module: Module<'ra>, + ident: Ident, + ns: Namespace, + parent_scope: &ParentScope<'ra>, + shadowing: Shadowing, + finalize: Option, + // This binding should be ignored during in-module resolution, so that we don't get + // "self-confirming" import resolutions during import validation and checking. + ignore_binding: Option>, + ) -> Result, (Determinacy, Weak)> { let key = BindingKey::new(ident, ns); // `try_borrow_mut` is required to ensure exclusive access, even if the resulting binding // doesn't need to be mutable. It will fail when there is a cycle of imports, and without @@ -874,74 +978,135 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .try_borrow_mut() .map_err(|_| (Determined, Weak::No))?; - // If the primary binding is unusable, search further and return the shadowed glob - // binding if it exists. What we really want here is having two separate scopes in - // a module - one for non-globs and one for globs, but until that's done use this - // hack to avoid inconsistent resolution ICEs during import validation. - let binding = [resolution.non_glob_binding, resolution.glob_binding] - .into_iter() - .find_map(|binding| if binding == ignore_binding { None } else { binding }); - - if let Some(finalize) = finalize { - return self.get_mut().finalize_module_binding( - ident, - binding, - if resolution.non_glob_binding.is_some() { resolution.glob_binding } else { None }, - parent_scope, - finalize, - shadowing, - ); + if let Some(binding) = resolution.non_glob_binding + && ignore_binding.map_or(true, |b| binding != b) + { + if let Some(finalize) = finalize { + return self.get_mut().finalize_module_binding( + ident, + binding, + resolution.glob_binding, + parent_scope, + finalize, + shadowing, + ); + } else { + let usable = self.is_accessible_from(binding.vis, parent_scope.module); + if usable { + return Ok(binding); + } else { + return Err((Determined, Weak::No)); + }; + } } - let check_usable = |this: CmResolver<'r, 'ra, 'tcx>, binding: NameBinding<'ra>| { - let usable = this.is_accessible_from(binding.vis, parent_scope.module); - if usable { Ok(binding) } else { Err((Determined, Weak::No)) } - }; + Err((Determinacy::determined(finalize.is_some()), Weak::Yes)) + } - // Items and single imports are not shadowable, if we have one, then it's determined. - if let Some(binding) = binding - && !binding.is_glob_import() - { - return check_usable(self, binding); - } + fn resolve_ident_in_glob_module_unadjusted<'r>( + mut self: CmResolver<'r, 'ra, 'tcx>, + module: Module<'ra>, + ident: Ident, + ns: Namespace, + parent_scope: &ParentScope<'ra>, + shadowing: Shadowing, + finalize: Option, + // This binding should be ignored during in-module resolution, so that we don't get + // "self-confirming" import resolutions during import validation and checking. + ignore_binding: Option>, + ignore_import: Option>, + ) -> Result, (Determinacy, Weak)> { + let key = BindingKey::new(ident, ns); + let resolution = self + .resolution_or_default(module, key) + .try_borrow_mut() + .map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports. - // --- From now on we either have a glob resolution or no resolution. --- + if let Some(binding) = resolution.glob_binding + && ignore_binding.map_or(true, |b| binding != b) + { + if let Some(finalize) = finalize { + return self.get_mut().finalize_module_binding( + ident, + binding, + None, + parent_scope, + finalize, + shadowing, + ); + } - // Check if one of single imports can still define the name, - // if it can then our result is not determined and can be invalidated. - if self.reborrow().single_import_can_define_name( - &resolution, - binding, - ns, - ignore_import, - ignore_binding, - parent_scope, - ) { - return Err((Undetermined, Weak::No)); - } + // Check if a single import can still define the name, + // if it can then our result is not determined and can be invalidated. + if self.reborrow().single_import_can_define_name( + &resolution, + Some(binding), + ns, + ignore_import, + ignore_binding, + parent_scope, + ) { + return Err((Undetermined, Weak::No)); + } - // So we have a resolution that's from a glob import. This resolution is determined - // if it cannot be shadowed by some new item/import expanded from a macro. - // This happens either if there are no unexpanded macros, or expanded names cannot - // shadow globs (that happens in macro namespace or with restricted shadowing). - // - // Additionally, any macro in any module can plant names in the root module if it creates - // `macro_export` macros, so the root module effectively has unresolved invocations if any - // module has unresolved invocations. - // However, it causes resolution/expansion to stuck too often (#53144), so, to make - // progress, we have to ignore those potential unresolved invocations from other modules - // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted - // shadowing is enabled, see `macro_expanded_macro_export_errors`). - if let Some(binding) = binding { + // So we have a resolution that's from a glob import. This resolution is determined + // if it cannot be shadowed by some new item/import expanded from a macro. + // This happens either if there are no unexpanded macros, or expanded names cannot + // shadow globs (that happens in macro namespace or with restricted shadowing). + // + // Additionally, any macro in any module can plant names in the root module if it creates + // `macro_export` macros, so the root module effectively has unresolved invocations if any + // module has unresolved invocations. + // However, it causes resolution/expansion to stuck too often (#53144), so, to make + // progress, we have to ignore those potential unresolved invocations from other modules + // and prohibit access to macro-expanded `macro_export` macros instead (unless restricted + // shadowing is enabled, see `macro_expanded_macro_export_errors`). if binding.determined() || ns == MacroNS || shadowing == Shadowing::Restricted { - return check_usable(self, binding); + let usable = self.is_accessible_from(binding.vis, parent_scope.module); + if usable { + return Ok(binding); + } else { + return Err((Determined, Weak::No)); + }; } else { return Err((Undetermined, Weak::No)); } - } + } else if finalize.is_some() { + return Err((Determined, Weak::No)); + } else { + // Check if a single import can still define the name, + // if it can then our result is not determined and can be invalidated. + if self.reborrow().single_import_can_define_name( + &resolution, + None, + ns, + ignore_import, + ignore_binding, + parent_scope, + ) { + return Err((Undetermined, Weak::No)); + } - // --- From now on we have no resolution. --- + return Err(self.create_resolution_in_module_error( + module, + ident, + ns, + parent_scope, + ignore_binding, + ignore_import, + )); + } + } + fn create_resolution_in_module_error<'r>( + mut self: CmResolver<'r, 'ra, 'tcx>, + module: Module<'ra>, + ident: Ident, + ns: Namespace, + parent_scope: &ParentScope<'ra>, + ignore_binding: Option>, + ignore_import: Option>, + ) -> (Determinacy, Weak) { // Now we are in situation when new item/import can appear only from a glob or a macro // expansion. With restricted shadowing names from globs and macro expansions cannot // shadow names from outer scopes, so we can freely fallback from module search to search @@ -951,7 +1116,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Check if one of unexpanded macros can still define the name, // if it can then our "no resolution" result is not determined and can be invalidated. if !module.unexpanded_invocations.borrow().is_empty() { - return Err((Undetermined, Weak::Yes)); + return (Undetermined, Weak::Yes); } // Check if one of glob imports can still define the name, @@ -966,8 +1131,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let module = match glob_import.imported_module.get() { Some(ModuleOrUniformRoot::Module(module)) => module, Some(_) => continue, - None => return Err((Undetermined, Weak::Yes)), + None => return (Undetermined, Weak::Yes), }; + let tmp_parent_scope; let (mut adjusted_parent_scope, mut ident) = (parent_scope, ident.normalize_to_macros_2_0()); @@ -985,42 +1151,37 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ident, ns, adjusted_parent_scope, - Shadowing::Unrestricted, None, ignore_binding, ignore_import, ); match result { - Err((Determined, _)) => continue, + Err(Determined) => continue, Ok(binding) if !self.is_accessible_from(binding.vis, glob_import.parent_scope.module) => { continue; } - Ok(_) | Err((Undetermined, _)) => return Err((Undetermined, Weak::Yes)), + Ok(_) | Err(Undetermined) => return (Undetermined, Weak::Yes), } } // No resolution and no one else can define the name - determinate error. - Err((Determined, Weak::No)) + (Determined, Weak::No) } fn finalize_module_binding( &mut self, ident: Ident, - binding: Option>, - shadowed_glob: Option>, + binding: NameBinding<'ra>, + glob_binding: Option>, parent_scope: &ParentScope<'ra>, finalize: Finalize, shadowing: Shadowing, ) -> Result, (Determinacy, Weak)> { let Finalize { path_span, report_private, used, root_span, .. } = finalize; - let Some(binding) = binding else { - return Err((Determined, Weak::No)); - }; - if !self.is_accessible_from(binding.vis, parent_scope.module) { if report_private { self.privacy_errors.push(PrivacyError { @@ -1038,7 +1199,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } // Forbid expanded shadowing to avoid time travel. - if let Some(shadowed_glob) = shadowed_glob + // FIXME it should be possible to output a MoreExpandedVsOuter ambiguity error + // instead of GlobVsExpanded, but that presumably has to be done in a different location. + if let Some(shadowed_glob) = glob_binding && shadowing == Shadowing::Restricted && binding.expansion != LocalExpnId::ROOT && binding.res() != shadowed_glob.res() @@ -1114,13 +1277,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { ignore_binding, ignore_import, ) { - Err((Determined, _)) => continue, + Err(Determined) => continue, Ok(binding) if !self.is_accessible_from(binding.vis, single_import.parent_scope.module) => { continue; } - Ok(_) | Err((Undetermined, _)) => { + Ok(_) | Err(Undetermined) => { return true; } } @@ -1599,17 +1762,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } let binding = if let Some(module) = module { - self.reborrow() - .resolve_ident_in_module( - module, - ident, - ns, - parent_scope, - finalize, - ignore_binding, - ignore_import, - ) - .map_err(|(determinacy, _)| determinacy) + self.reborrow().resolve_ident_in_module( + module, + ident, + ns, + parent_scope, + finalize, + ignore_binding, + ignore_import, + ) } else if let Some(ribs) = ribs && let Some(TypeNS | ValueNS) = opt_ns { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ca9c124fca63c..f212e838118bc 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -126,11 +126,12 @@ enum Scope<'ra> { DeriveHelpersCompat, /// Textual `let`-like scopes introduced by `macro_rules!` items. MacroRules(MacroRulesScopeRef<'ra>), - /// Names declared in the given module. - /// The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` - /// lint if it should be reported. - Module(Module<'ra>, Option), - /// Names introduced by `#[macro_use]` attributes on `extern crate` items. + // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` + // lint if it should be reported. + NonGlobModule(Module<'ra>, Option), + // The node ID is for reporting the `PROC_MACRO_DERIVE_RESOLUTION_FALLBACK` + // lint if it should be reported. + GlobModule(Module<'ra>, Option), MacroUsePrelude, /// Built-in attributes. BuiltinAttrs, @@ -161,6 +162,8 @@ enum ScopeSet<'ra> { /// All scopes with the given namespace, used for partially performing late resolution. /// The node id enables lints and is used for reporting them. Late(Namespace, Module<'ra>, Option), + /// Scope::NonGlobModule and Scope::GlobModule. + Module(Namespace, Module<'ra>), } /// Everything you need to know about a name's location to resolve it. @@ -1883,9 +1886,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { self.cm().visit_scopes(ScopeSet::All(TypeNS), parent_scope, ctxt, |this, scope, _, _| { match scope { - Scope::Module(module, _) => { + Scope::NonGlobModule(module, _) => { this.get_mut().traits_in_module(module, assoc_item, &mut found_traits); } + Scope::GlobModule(..) => { + // already inserted in `Scope::NonGlobModule` arm + } Scope::StdLibPrelude => { if let Some(module) = this.prelude { this.get_mut().traits_in_module(module, assoc_item, &mut found_traits); diff --git a/tests/ui/imports/import-after-macro-expand-10.rs b/tests/ui/imports/import-after-macro-expand-10.rs index eb04936a5feb7..9ca90babe936d 100644 --- a/tests/ui/imports/import-after-macro-expand-10.rs +++ b/tests/ui/imports/import-after-macro-expand-10.rs @@ -1,5 +1,3 @@ -//@ check-pass - mod b { pub mod http { pub struct HeaderMap; @@ -14,4 +12,5 @@ use crate::b::*; fn main() { let h: crate::b::HeaderMap = HeaderMap; + //~^ ERROR ambiguous } diff --git a/tests/ui/imports/import-after-macro-expand-10.stderr b/tests/ui/imports/import-after-macro-expand-10.stderr new file mode 100644 index 0000000000000..1948c14d766f0 --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-10.stderr @@ -0,0 +1,23 @@ +error[E0659]: `HeaderMap` is ambiguous + --> $DIR/import-after-macro-expand-10.rs:14:22 + | +LL | let h: crate::b::HeaderMap = HeaderMap; + | ^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `HeaderMap` could refer to the struct defined here + --> $DIR/import-after-macro-expand-10.rs:8:5 + | +LL | pub struct HeaderMap; + | ^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously +note: `HeaderMap` could also refer to the struct imported here + --> $DIR/import-after-macro-expand-10.rs:6:13 + | +LL | pub use self::http::*; + | ^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/import-after-macro-expand-11.rs b/tests/ui/imports/import-after-macro-expand-11.rs index 897c3001cc928..5c515bd3e8f0f 100644 --- a/tests/ui/imports/import-after-macro-expand-11.rs +++ b/tests/ui/imports/import-after-macro-expand-11.rs @@ -1,5 +1,3 @@ -//@ check-pass - #[derive(Debug)] struct H; @@ -14,6 +12,7 @@ mod p { fn f() { let h: crate::p::H = H; + //~^ ERROR ambiguous } } } diff --git a/tests/ui/imports/import-after-macro-expand-11.stderr b/tests/ui/imports/import-after-macro-expand-11.stderr new file mode 100644 index 0000000000000..c8affc701c714 --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-11.stderr @@ -0,0 +1,23 @@ +error[E0659]: `H` is ambiguous + --> $DIR/import-after-macro-expand-11.rs:14:29 + | +LL | let h: crate::p::H = H; + | ^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `H` could refer to the struct defined here + --> $DIR/import-after-macro-expand-11.rs:8:5 + | +LL | struct H; + | ^^^^^^^^^ + = help: use `self::H` to refer to this struct unambiguously +note: `H` could also refer to the struct imported here + --> $DIR/import-after-macro-expand-11.rs:5:9 + | +LL | use super::*; + | ^^^^^^^^ + = help: use `self::H` to refer to this struct unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/import-after-macro-expand-13.rs b/tests/ui/imports/import-after-macro-expand-13.rs index 016d897732d9f..ba2cf2561c273 100644 --- a/tests/ui/imports/import-after-macro-expand-13.rs +++ b/tests/ui/imports/import-after-macro-expand-13.rs @@ -1,4 +1,3 @@ -//@ check-pass // similar as `import-after-macro-expand-6.rs` use crate::a::HeaderMap; @@ -19,4 +18,5 @@ mod a { fn main() { let h: crate::b::HeaderMap = HeaderMap; + //~^ ERROR ambiguous } diff --git a/tests/ui/imports/import-after-macro-expand-13.stderr b/tests/ui/imports/import-after-macro-expand-13.stderr new file mode 100644 index 0000000000000..3dc1e5e19a4e9 --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-13.stderr @@ -0,0 +1,23 @@ +error[E0659]: `HeaderMap` is ambiguous + --> $DIR/import-after-macro-expand-13.rs:20:22 + | +LL | let h: crate::b::HeaderMap = HeaderMap; + | ^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `HeaderMap` could refer to the struct defined here + --> $DIR/import-after-macro-expand-13.rs:12:5 + | +LL | pub struct HeaderMap; + | ^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously +note: `HeaderMap` could also refer to the struct imported here + --> $DIR/import-after-macro-expand-13.rs:10:13 + | +LL | pub use self::http::*; + | ^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/import-after-macro-expand-14.rs b/tests/ui/imports/import-after-macro-expand-14.rs index 0af312f375efa..c78868353c653 100644 --- a/tests/ui/imports/import-after-macro-expand-14.rs +++ b/tests/ui/imports/import-after-macro-expand-14.rs @@ -1,5 +1,3 @@ -//@ check-pass - use crate::a::HeaderMap; mod b { @@ -19,4 +17,5 @@ mod a { fn main() { let h: crate::b::HeaderMap = HeaderMap; + //~^ ERROR ambiguous } diff --git a/tests/ui/imports/import-after-macro-expand-14.stderr b/tests/ui/imports/import-after-macro-expand-14.stderr new file mode 100644 index 0000000000000..9e899170caff2 --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-14.stderr @@ -0,0 +1,23 @@ +error[E0659]: `HeaderMap` is ambiguous + --> $DIR/import-after-macro-expand-14.rs:19:22 + | +LL | let h: crate::b::HeaderMap = HeaderMap; + | ^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `HeaderMap` could refer to the struct defined here + --> $DIR/import-after-macro-expand-14.rs:11:5 + | +LL | pub struct HeaderMap; + | ^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously +note: `HeaderMap` could also refer to the struct imported here + --> $DIR/import-after-macro-expand-14.rs:9:13 + | +LL | pub use self::http::*; + | ^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/import-after-macro-expand-2.rs b/tests/ui/imports/import-after-macro-expand-2.rs index f0b5fbf02d90d..7a5eeabb6a4e3 100644 --- a/tests/ui/imports/import-after-macro-expand-2.rs +++ b/tests/ui/imports/import-after-macro-expand-2.rs @@ -1,4 +1,3 @@ -//@ check-pass // https://github.com/rust-lang/rust/issues/56593#issuecomment-1133174514 use thing::*; @@ -13,6 +12,7 @@ mod tests { fn test_thing() { let thing: crate::Thing = Thing::Foo; + //~^ ERROR ambiguous } } diff --git a/tests/ui/imports/import-after-macro-expand-2.stderr b/tests/ui/imports/import-after-macro-expand-2.stderr new file mode 100644 index 0000000000000..d77c5ad729fb5 --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-2.stderr @@ -0,0 +1,25 @@ +error[E0659]: `Thing` is ambiguous + --> $DIR/import-after-macro-expand-2.rs:14:27 + | +LL | let thing: crate::Thing = Thing::Foo; + | ^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `Thing` could refer to the enum defined here + --> $DIR/import-after-macro-expand-2.rs:6:1 + | +LL | / pub enum Thing { +LL | | Foo +LL | | } + | |_^ + = help: use `crate::Thing` to refer to this enum unambiguously +note: `Thing` could also refer to the enum imported here + --> $DIR/import-after-macro-expand-2.rs:3:5 + | +LL | use thing::*; + | ^^^^^^^^ + = help: use `crate::Thing` to refer to this enum unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/import-after-macro-expand-6.rs b/tests/ui/imports/import-after-macro-expand-6.rs index 73dce5985a841..60e4cd0a27510 100644 --- a/tests/ui/imports/import-after-macro-expand-6.rs +++ b/tests/ui/imports/import-after-macro-expand-6.rs @@ -1,4 +1,3 @@ -//@ check-pass // https://github.com/rust-lang/rust/pull/113099#issuecomment-1633574396 pub mod a { @@ -19,4 +18,5 @@ use crate::a::HeaderMap; fn main() { let h: crate::b::HeaderMap = HeaderMap; + //~^ ERROR ambiguous } diff --git a/tests/ui/imports/import-after-macro-expand-6.stderr b/tests/ui/imports/import-after-macro-expand-6.stderr new file mode 100644 index 0000000000000..a71c82cc534fd --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-6.stderr @@ -0,0 +1,23 @@ +error[E0659]: `HeaderMap` is ambiguous + --> $DIR/import-after-macro-expand-6.rs:20:22 + | +LL | let h: crate::b::HeaderMap = HeaderMap; + | ^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `HeaderMap` could refer to the struct defined here + --> $DIR/import-after-macro-expand-6.rs:14:5 + | +LL | pub struct HeaderMap; + | ^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously +note: `HeaderMap` could also refer to the struct imported here + --> $DIR/import-after-macro-expand-6.rs:12:13 + | +LL | pub use self::http::*; + | ^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/import-after-macro-expand-9.rs b/tests/ui/imports/import-after-macro-expand-9.rs index 5caac06e7b984..8df7be0809c9e 100644 --- a/tests/ui/imports/import-after-macro-expand-9.rs +++ b/tests/ui/imports/import-after-macro-expand-9.rs @@ -1,5 +1,3 @@ -//@ check-pass - use crate::b::*; mod b { @@ -14,4 +12,5 @@ mod b { fn main() { let h: crate::b::HeaderMap = HeaderMap; + //~^ ERROR ambiguous } diff --git a/tests/ui/imports/import-after-macro-expand-9.stderr b/tests/ui/imports/import-after-macro-expand-9.stderr new file mode 100644 index 0000000000000..8217a95b164f3 --- /dev/null +++ b/tests/ui/imports/import-after-macro-expand-9.stderr @@ -0,0 +1,23 @@ +error[E0659]: `HeaderMap` is ambiguous + --> $DIR/import-after-macro-expand-9.rs:14:22 + | +LL | let h: crate::b::HeaderMap = HeaderMap; + | ^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `HeaderMap` could refer to the struct defined here + --> $DIR/import-after-macro-expand-9.rs:10:5 + | +LL | pub struct HeaderMap; + | ^^^^^^^^^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously +note: `HeaderMap` could also refer to the struct imported here + --> $DIR/import-after-macro-expand-9.rs:8:13 + | +LL | pub use self::http::*; + | ^^^^^^^^^^^^^ + = help: use `self::HeaderMap` to refer to this struct unambiguously + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/imports.rs b/tests/ui/imports/imports.rs index b5c25eb044724..e3ef388a86622 100644 --- a/tests/ui/imports/imports.rs +++ b/tests/ui/imports/imports.rs @@ -1,4 +1,3 @@ -//@ run-pass #![allow(unused)] // Like other items, private imports can be imported and used non-lexically in paths. @@ -22,6 +21,7 @@ fn g() { use crate::bar::*; fn f() -> bool { true } let _: bool = f(); + //~^ ERROR `f` is ambiguous } fn h() { @@ -29,6 +29,7 @@ fn h() { use crate::bar::*; use crate::f; let _: bool = f(); + //~^ ERROR `f` is ambiguous } // Here, there appears to be shadowing but isn't because of namespaces. diff --git a/tests/ui/imports/imports.stderr b/tests/ui/imports/imports.stderr new file mode 100644 index 0000000000000..3267611231280 --- /dev/null +++ b/tests/ui/imports/imports.stderr @@ -0,0 +1,43 @@ +error[E0659]: `f` is ambiguous + --> $DIR/imports.rs:23:19 + | +LL | let _: bool = f(); + | ^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function imported here + --> $DIR/imports.rs:20:9 + | +LL | use crate::foo::*; + | ^^^^^^^^^^^^^ + = help: consider adding an explicit import of `f` to disambiguate +note: `f` could also refer to the function imported here + --> $DIR/imports.rs:21:9 + | +LL | use crate::bar::*; + | ^^^^^^^^^^^^^ + = help: consider adding an explicit import of `f` to disambiguate + +error[E0659]: `f` is ambiguous + --> $DIR/imports.rs:31:19 + | +LL | let _: bool = f(); + | ^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function imported here + --> $DIR/imports.rs:28:9 + | +LL | use crate::foo::*; + | ^^^^^^^^^^^^^ + = help: consider adding an explicit import of `f` to disambiguate +note: `f` could also refer to the function imported here + --> $DIR/imports.rs:29:9 + | +LL | use crate::bar::*; + | ^^^^^^^^^^^^^ + = help: consider adding an explicit import of `f` to disambiguate + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/issue-114682-1.rs b/tests/ui/imports/issue-114682-1.rs index 88fe05e51444d..7640915e7d9b8 100644 --- a/tests/ui/imports/issue-114682-1.rs +++ b/tests/ui/imports/issue-114682-1.rs @@ -22,4 +22,5 @@ mac!(); fn main() { A!(); //~^ ERROR `A` is ambiguous + //~^^ ERROR `A` is ambiguous } diff --git a/tests/ui/imports/issue-114682-1.stderr b/tests/ui/imports/issue-114682-1.stderr index 85fb7f7919e4e..de8dc6cfb9ff5 100644 --- a/tests/ui/imports/issue-114682-1.stderr +++ b/tests/ui/imports/issue-114682-1.stderr @@ -23,6 +23,32 @@ LL | pub use m::*; = help: consider adding an explicit import of `A` to disambiguate = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 1 previous error +error[E0659]: `A` is ambiguous + --> $DIR/issue-114682-1.rs:23:5 + | +LL | A!(); + | ^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `A` could refer to the macro defined here + --> $DIR/issue-114682-1.rs:7:9 + | +LL | / pub macro A() { +LL | | println!("non import") +LL | | } + | |_________^ +... +LL | mac!(); + | ------ in this macro invocation + = help: use `crate::A` to refer to this macro unambiguously +note: `A` could also refer to the macro imported here + --> $DIR/issue-114682-1.rs:19:9 + | +LL | pub use m::*; + | ^^^^ + = help: use `crate::A` to refer to this macro unambiguously + = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.rs b/tests/ui/imports/local-modularized-tricky-fail-1.rs index ce700ae0de9b1..781014a455a6b 100644 --- a/tests/ui/imports/local-modularized-tricky-fail-1.rs +++ b/tests/ui/imports/local-modularized-tricky-fail-1.rs @@ -27,6 +27,7 @@ mod inner1 { } exported!(); //~ ERROR `exported` is ambiguous +//~^ ERROR `exported` is ambiguous mod inner2 { define_exported!(); diff --git a/tests/ui/imports/local-modularized-tricky-fail-1.stderr b/tests/ui/imports/local-modularized-tricky-fail-1.stderr index 52a01e8bcdfe3..54d928f7c8121 100644 --- a/tests/ui/imports/local-modularized-tricky-fail-1.stderr +++ b/tests/ui/imports/local-modularized-tricky-fail-1.stderr @@ -23,8 +23,34 @@ LL | use inner1::*; = help: consider adding an explicit import of `exported` to disambiguate = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) +error[E0659]: `exported` is ambiguous + --> $DIR/local-modularized-tricky-fail-1.rs:29:1 + | +LL | exported!(); + | ^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `exported` could refer to the macro defined here + --> $DIR/local-modularized-tricky-fail-1.rs:6:5 + | +LL | / macro_rules! exported { +LL | | () => () +LL | | } + | |_____^ +... +LL | define_exported!(); + | ------------------ in this macro invocation + = help: use `crate::exported` to refer to this macro unambiguously +note: `exported` could also refer to the macro imported here + --> $DIR/local-modularized-tricky-fail-1.rs:23:5 + | +LL | use inner1::*; + | ^^^^^^^^^ + = help: use `crate::exported` to refer to this macro unambiguously + = note: this error originates in the macro `define_exported` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0659]: `panic` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:36:5 + --> $DIR/local-modularized-tricky-fail-1.rs:37:5 | LL | panic!(); | ^^^^^ ambiguous name @@ -45,7 +71,7 @@ LL | define_panic!(); = note: this error originates in the macro `define_panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0659]: `include` is ambiguous - --> $DIR/local-modularized-tricky-fail-1.rs:47:1 + --> $DIR/local-modularized-tricky-fail-1.rs:48:1 | LL | include!(); | ^^^^^^^ ambiguous name @@ -65,6 +91,6 @@ LL | define_include!(); = help: use `crate::include` to refer to this macro unambiguously = note: this error originates in the macro `define_include` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/macro-paths.rs b/tests/ui/imports/macro-paths.rs index 916442a7c4eab..fd77cf52c8953 100644 --- a/tests/ui/imports/macro-paths.rs +++ b/tests/ui/imports/macro-paths.rs @@ -11,6 +11,7 @@ mod foo { fn f() { use foo::*; bar::m! { //~ ERROR ambiguous + //~^ ERROR ambiguous mod bar { pub use two_macros::m; } } } diff --git a/tests/ui/imports/macro-paths.stderr b/tests/ui/imports/macro-paths.stderr index 5f113ce2bee5d..5ba92072805e3 100644 --- a/tests/ui/imports/macro-paths.stderr +++ b/tests/ui/imports/macro-paths.stderr @@ -6,7 +6,7 @@ LL | bar::m! { | = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution note: `bar` could refer to the module defined here - --> $DIR/macro-paths.rs:14:9 + --> $DIR/macro-paths.rs:15:9 | LL | mod bar { pub use two_macros::m; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,20 +17,38 @@ LL | use foo::*; | ^^^^^^ = help: consider adding an explicit import of `bar` to disambiguate +error[E0659]: `bar` is ambiguous + --> $DIR/macro-paths.rs:13:5 + | +LL | bar::m! { + | ^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `bar` could refer to the module defined here + --> $DIR/macro-paths.rs:15:9 + | +LL | mod bar { pub use two_macros::m; } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: `bar` could also refer to the module imported here + --> $DIR/macro-paths.rs:12:9 + | +LL | use foo::*; + | ^^^^^^ + error[E0659]: `baz` is ambiguous - --> $DIR/macro-paths.rs:23:5 + --> $DIR/macro-paths.rs:24:5 | LL | baz::m! { | ^^^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `baz` could refer to the module defined here - --> $DIR/macro-paths.rs:24:9 + --> $DIR/macro-paths.rs:25:9 | LL | mod baz { pub use two_macros::m; } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: `baz` could also refer to the module defined here - --> $DIR/macro-paths.rs:18:1 + --> $DIR/macro-paths.rs:19:1 | LL | / pub mod baz { LL | | pub use two_macros::m; @@ -38,6 +56,6 @@ LL | | } | |_^ = help: use `crate::baz` to refer to this module unambiguously -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/macros.rs b/tests/ui/imports/macros.rs index cf67e08c87a30..910cd9503050e 100644 --- a/tests/ui/imports/macros.rs +++ b/tests/ui/imports/macros.rs @@ -14,6 +14,7 @@ mod m1 { mod m2 { use two_macros::*; m! { //~ ERROR ambiguous + //~^ ERROR ambiguous use crate::foo::m; } } diff --git a/tests/ui/imports/macros.stderr b/tests/ui/imports/macros.stderr index 25a678c6b3751..2642525816bd6 100644 --- a/tests/ui/imports/macros.stderr +++ b/tests/ui/imports/macros.stderr @@ -6,7 +6,7 @@ LL | m! { | = note: ambiguous because of a conflict between a name from a glob import and a macro-expanded name in the same module during import or macro resolution note: `m` could refer to the macro imported here - --> $DIR/macros.rs:17:13 + --> $DIR/macros.rs:18:13 | LL | use crate::foo::m; | ^^^^^^^^^^^^^ @@ -18,24 +18,44 @@ LL | use two_macros::*; = help: consider adding an explicit import of `m` to disambiguate error[E0659]: `m` is ambiguous - --> $DIR/macros.rs:29:9 + --> $DIR/macros.rs:16:5 + | +LL | m! { + | ^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `m` could refer to the macro imported here + --> $DIR/macros.rs:18:13 + | +LL | use crate::foo::m; + | ^^^^^^^^^^^^^ + = help: use `self::m` to refer to this macro unambiguously +note: `m` could also refer to the macro imported here + --> $DIR/macros.rs:15:9 + | +LL | use two_macros::*; + | ^^^^^^^^^^^^^ + = help: use `self::m` to refer to this macro unambiguously + +error[E0659]: `m` is ambiguous + --> $DIR/macros.rs:30:9 | LL | m! { | ^ ambiguous name | = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution note: `m` could refer to the macro imported here - --> $DIR/macros.rs:30:17 + --> $DIR/macros.rs:31:17 | LL | use two_macros::n as m; | ^^^^^^^^^^^^^^^^^^ note: `m` could also refer to the macro imported here - --> $DIR/macros.rs:22:9 + --> $DIR/macros.rs:23:9 | LL | use two_macros::m; | ^^^^^^^^^^^^^ = help: use `self::m` to refer to this macro unambiguously -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/resolve/issue-109153.rs b/tests/ui/resolve/issue-109153.rs index bff6c911236e6..1bfb5f2adb49f 100644 --- a/tests/ui/resolve/issue-109153.rs +++ b/tests/ui/resolve/issue-109153.rs @@ -10,5 +10,6 @@ mod foo { use bar::bar; //~ ERROR `bar` is ambiguous use bar::*; +//~^ ERROR `bar` is ambiguous fn main() { } diff --git a/tests/ui/resolve/issue-109153.stderr b/tests/ui/resolve/issue-109153.stderr index da95029f6e783..9d703bdfd2ded 100644 --- a/tests/ui/resolve/issue-109153.stderr +++ b/tests/ui/resolve/issue-109153.stderr @@ -18,6 +18,26 @@ LL | use bar::*; | ^^^^^^ = help: consider adding an explicit import of `bar` to disambiguate -error: aborting due to 1 previous error +error[E0659]: `bar` is ambiguous + --> $DIR/issue-109153.rs:12:5 + | +LL | use bar::*; + | ^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `bar` could refer to the module imported here + --> $DIR/issue-109153.rs:1:5 + | +LL | use foo::*; + | ^^^^^^ + = help: consider adding an explicit import of `bar` to disambiguate +note: `bar` could also refer to the module imported here + --> $DIR/issue-109153.rs:12:5 + | +LL | use bar::*; + | ^^^^^^ + = help: consider adding an explicit import of `bar` to disambiguate + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/underscore-imports/shadow.rs b/tests/ui/underscore-imports/shadow.rs index 325f2001b9ede..a2f8855cf7535 100644 --- a/tests/ui/underscore-imports/shadow.rs +++ b/tests/ui/underscore-imports/shadow.rs @@ -14,9 +14,10 @@ mod b { mod c { use crate::b::Shadow as _; // Only imports the struct + //~^ ERROR `Shadow` is ambiguous fn f(x: &()) { - x.deref(); //~ ERROR no method named `deref` found + x.deref() //~ ERROR no method named `deref` found } } diff --git a/tests/ui/underscore-imports/shadow.stderr b/tests/ui/underscore-imports/shadow.stderr index 4743d14dfb9e6..7b322ec1b6371 100644 --- a/tests/ui/underscore-imports/shadow.stderr +++ b/tests/ui/underscore-imports/shadow.stderr @@ -1,7 +1,31 @@ +error[E0659]: `Shadow` is ambiguous + --> $DIR/shadow.rs:16:19 + | +LL | use crate::b::Shadow as _; // Only imports the struct + | ^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution +note: `Shadow` could refer to the struct defined here + --> $DIR/shadow.rs:10:25 + | +LL | ($i:ident) => { pub struct $i; } + | ^^^^^^^^^^^^^^ +LL | } +LL | m!(Shadow); + | ---------- in this macro invocation + = help: use `self::Shadow` to refer to this struct unambiguously +note: `Shadow` could also refer to the trait imported here + --> $DIR/shadow.rs:8:13 + | +LL | pub use crate::a::*; + | ^^^^^^^^^^^ + = help: use `self::Shadow` to refer to this trait unambiguously + = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + error[E0599]: no method named `deref` found for reference `&()` in the current scope - --> $DIR/shadow.rs:19:11 + --> $DIR/shadow.rs:20:11 | -LL | x.deref(); +LL | x.deref() | ^^^^^ method not found in `&()` | = help: items from traits can only be used if the trait is in scope @@ -10,6 +34,7 @@ help: trait `Deref` which provides `deref` is implemented but not in scope; perh LL + use std::ops::Deref; | -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0599`. +Some errors have detailed explanations: E0599, E0659. +For more information about an error, try `rustc --explain E0599`.