From 45272bbeca65b5d38a8a2a6c61fdb606612189c0 Mon Sep 17 00:00:00 2001 From: bohan Date: Sat, 18 Nov 2023 23:56:52 +0800 Subject: [PATCH] resolve: re-export ambiguity in extern crate as warning --- compiler/rustc_errors/src/lib.rs | 3 + compiler/rustc_lint_defs/src/lib.rs | 2 + compiler/rustc_metadata/src/rmeta/decoder.rs | 15 +++ .../src/rmeta/decoder/cstore_impl.rs | 12 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 + compiler/rustc_metadata/src/rmeta/mod.rs | 3 +- compiler/rustc_middle/src/metadata.rs | 3 + compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_middle/src/ty/mod.rs | 3 +- .../rustc_resolve/src/build_reduced_graph.rs | 104 ++++++++++++------ compiler/rustc_resolve/src/diagnostics.rs | 13 ++- compiler/rustc_resolve/src/ident.rs | 1 + compiler/rustc_resolve/src/imports.rs | 32 ++++-- compiler/rustc_resolve/src/lib.rs | 37 +++++-- compiler/rustc_resolve/src/macros.rs | 2 +- tests/ui/imports/ambiguous-4.rs | 1 - .../glob-conflict-cross-crate-2-extern.rs | 10 ++ .../auxiliary/issue-114682-2-extern.rs | 17 +++ .../auxiliary/issue-114682-3-extern.rs | 16 +++ .../auxiliary/issue-114682-4-extern.rs | 10 ++ .../auxiliary/issue-114682-5-extern-1.rs | 1 + .../auxiliary/issue-114682-5-extern-2.rs | 13 +++ .../auxiliary/issue-114682-6-extern.rs | 9 ++ tests/ui/imports/extern-with-ambiguous-2.rs | 2 +- .../ui/imports/extern-with-ambiguous-2.stderr | 23 ++++ tests/ui/imports/extern-with-ambiguous-3.rs | 2 +- .../ui/imports/extern-with-ambiguous-3.stderr | 23 ++++ .../ui/imports/glob-conflict-cross-crate-1.rs | 8 ++ .../glob-conflict-cross-crate-1.stderr | 29 +++++ .../ui/imports/glob-conflict-cross-crate-2.rs | 12 ++ .../glob-conflict-cross-crate-2.stderr | 18 +++ .../ui/imports/glob-conflict-cross-crate-3.rs | 17 +++ .../glob-conflict-cross-crate-3.stderr | 25 +++++ tests/ui/imports/glob-conflict-cross-crate.rs | 8 -- .../imports/glob-conflict-cross-crate.stderr | 15 --- tests/ui/imports/issue-114682-1.rs | 25 +++++ tests/ui/imports/issue-114682-1.stderr | 28 +++++ tests/ui/imports/issue-114682-2.rs | 9 ++ tests/ui/imports/issue-114682-2.stderr | 16 +++ tests/ui/imports/issue-114682-3.rs | 23 ++++ tests/ui/imports/issue-114682-3.stderr | 13 +++ tests/ui/imports/issue-114682-4.rs | 15 +++ tests/ui/imports/issue-114682-4.stderr | 33 ++++++ tests/ui/imports/issue-114682-5.rs | 16 +++ tests/ui/imports/issue-114682-5.stderr | 48 ++++++++ tests/ui/imports/issue-114682-6.rs | 14 +++ tests/ui/imports/issue-114682-6.stderr | 18 +++ 47 files changed, 671 insertions(+), 84 deletions(-) create mode 100644 tests/ui/imports/auxiliary/glob-conflict-cross-crate-2-extern.rs create mode 100644 tests/ui/imports/auxiliary/issue-114682-2-extern.rs create mode 100644 tests/ui/imports/auxiliary/issue-114682-3-extern.rs create mode 100644 tests/ui/imports/auxiliary/issue-114682-4-extern.rs create mode 100644 tests/ui/imports/auxiliary/issue-114682-5-extern-1.rs create mode 100644 tests/ui/imports/auxiliary/issue-114682-5-extern-2.rs create mode 100644 tests/ui/imports/auxiliary/issue-114682-6-extern.rs create mode 100644 tests/ui/imports/extern-with-ambiguous-2.stderr create mode 100644 tests/ui/imports/extern-with-ambiguous-3.stderr create mode 100644 tests/ui/imports/glob-conflict-cross-crate-1.rs create mode 100644 tests/ui/imports/glob-conflict-cross-crate-1.stderr create mode 100644 tests/ui/imports/glob-conflict-cross-crate-2.rs create mode 100644 tests/ui/imports/glob-conflict-cross-crate-2.stderr create mode 100644 tests/ui/imports/glob-conflict-cross-crate-3.rs create mode 100644 tests/ui/imports/glob-conflict-cross-crate-3.stderr delete mode 100644 tests/ui/imports/glob-conflict-cross-crate.rs delete mode 100644 tests/ui/imports/glob-conflict-cross-crate.stderr create mode 100644 tests/ui/imports/issue-114682-1.rs create mode 100644 tests/ui/imports/issue-114682-1.stderr create mode 100644 tests/ui/imports/issue-114682-2.rs create mode 100644 tests/ui/imports/issue-114682-2.stderr create mode 100644 tests/ui/imports/issue-114682-3.rs create mode 100644 tests/ui/imports/issue-114682-3.stderr create mode 100644 tests/ui/imports/issue-114682-4.rs create mode 100644 tests/ui/imports/issue-114682-4.stderr create mode 100644 tests/ui/imports/issue-114682-5.rs create mode 100644 tests/ui/imports/issue-114682-5.stderr create mode 100644 tests/ui/imports/issue-114682-6.rs create mode 100644 tests/ui/imports/issue-114682-6.stderr diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index b97ec02675a60..c3cbf600e3198 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1695,6 +1695,9 @@ pub fn report_ambiguity_error<'a, G: EmissionGuarantee>( for help_msg in ambiguity.b1_help_msgs { db.help(help_msg); } + if ambiguity.extern_crate { + return; + } db.span_note(ambiguity.b2_span, ambiguity.b2_note_msg); for help_msg in ambiguity.b2_help_msgs { db.help(help_msg); diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index eed35326c4501..92a9688c40455 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -553,6 +553,8 @@ impl StableCompare for LintId { #[derive(Debug)] pub struct AmbiguityErrorDiag { + /// Does this ambiguity binding come from a different crate? + pub extern_crate: bool, pub msg: String, pub span: Span, pub label_span: Span, diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 49e849964be47..48243b3e7119e 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1250,6 +1250,21 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { }) } + fn get_ambiguity_module_children( + self, + id: DefIndex, + sess: &'a Session, + ) -> impl Iterator + 'a { + iter::from_coroutine(move || { + let children = self.root.tables.ambiguity_module_children.get(self, id); + if !children.is_default() { + for child in children.decode((self, sess)) { + yield child; + } + } + }) + } + fn is_ctfe_mir_available(self, id: DefIndex) -> bool { self.root.tables.mir_for_ctfe.get(self, id).is_some() } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 912c2f36eb3c8..48f28b6fccd30 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -11,7 +11,7 @@ use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; use rustc_middle::arena::ArenaAllocatable; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{AmbiguityModChild, ModChild}; use rustc_middle::middle::exported_symbols::ExportedSymbol; use rustc_middle::middle::stability::DeprecationEntry; use rustc_middle::query::ExternProviders; @@ -581,6 +581,16 @@ impl CStore { self.get_crate_data_mut(cnum).dependencies = dependencies; } } + + pub fn ambiguity_module_children_untracked( + &self, + def_id: DefId, + sess: &Session, + ) -> Vec { + self.get_crate_data(def_id.krate) + .get_ambiguity_module_children(def_id.index, sess) + .collect() + } } impl CrateStore for CStore { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index a458b528a97cb..83ca3dfb75c31 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1568,6 +1568,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_defaulted_array!(self.tables.module_children_reexports[def_id] <- module_children.iter().filter(|child| !child.reexport_chain.is_empty())); + + record_defaulted_array!(self.tables.ambiguity_module_children[def_id] <- tcx.ambiguity_module_children_local(local_def_id)); } } diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 2f77588269345..9041f96ece537 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -17,7 +17,7 @@ use rustc_hir::definitions::DefKey; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{AmbiguityModChild, ModChild}; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo}; use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault; @@ -398,6 +398,7 @@ define_tables! { // individually instead of `DefId`s. module_children_reexports: Table>, cross_crate_inlinable: Table, + ambiguity_module_children: Table>, - optional: attributes: Table>, diff --git a/compiler/rustc_middle/src/metadata.rs b/compiler/rustc_middle/src/metadata.rs index 674402cb4bf9b..aaf5a4656380d 100644 --- a/compiler/rustc_middle/src/metadata.rs +++ b/compiler/rustc_middle/src/metadata.rs @@ -44,3 +44,6 @@ pub struct ModChild { /// Empty if the module child is a proper item. pub reexport_chain: SmallVec<[Reexport; 2]>, } + +/// Same as `ModChild`, however, it includes ambiguity error. +pub type AmbiguityModChild = ModChild; diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6807eacb7f177..7bcefab5f44f2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -8,7 +8,7 @@ use crate::arena::Arena; use crate::dep_graph::{DepGraph, DepKindStruct}; use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos}; use crate::lint::struct_lint_level; -use crate::metadata::ModChild; +use crate::metadata::{AmbiguityModChild, ModChild}; use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::resolve_bound_vars; use crate::middle::stability; @@ -2286,6 +2286,10 @@ impl<'tcx> TyCtxt<'tcx> { pub fn module_children_local(self, def_id: LocalDefId) -> &'tcx [ModChild] { self.resolutions(()).module_children.get(&def_id).map_or(&[], |v| &v[..]) } + + pub fn ambiguity_module_children_local(self, def_id: LocalDefId) -> &'tcx [AmbiguityModChild] { + self.resolutions(()).ambiguity_module_children.get(&def_id).map_or(&[], |v| &v[..]) + } } /// Parameter attributes that can only be determined by examining the body of a function instead diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9e8d7c2ef3ecb..a3d7f8957f63f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -18,7 +18,7 @@ pub use self::BorrowKind::*; pub use self::IntVarValue::*; pub use self::Variance::*; use crate::error::{OpaqueHiddenTypeMismatch, TypeMismatchReason}; -use crate::metadata::ModChild; +use crate::metadata::{AmbiguityModChild, ModChild}; use crate::middle::privacy::EffectiveVisibilities; use crate::mir::{Body, CoroutineLayout}; use crate::query::Providers; @@ -160,6 +160,7 @@ pub struct ResolverGlobalCtxt { pub extern_crate_map: FxHashMap, pub maybe_unused_trait_imports: FxIndexSet, pub module_children: LocalDefIdMap>, + pub ambiguity_module_children: LocalDefIdMap>, pub glob_map: FxHashMap>, pub main_def: Option, pub trait_impls: FxIndexMap>, diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index e176b8b4043c6..033dc80ba38a4 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -9,7 +9,7 @@ use crate::def_collector::collect_definitions; use crate::imports::{ImportData, ImportKind}; use crate::macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef}; use crate::Namespace::{self, MacroNS, TypeNS, ValueNS}; -use crate::{errors, BindingKey, MacroData, NameBindingData}; +use crate::{errors, AmbiguityKind, BindingKey, MacroData, NameBindingData}; use crate::{Determinacy, ExternPreludeEntry, Finalize, Module, ModuleKind, ModuleOrUniformRoot}; use crate::{NameBinding, NameBindingKind, ParentScope, PathResult, PerNS, ResolutionError}; use crate::{Resolver, ResolverArenas, Segment, ToNameBinding, VisResolutionError}; @@ -34,31 +34,45 @@ use std::cell::Cell; type Res = def::Res; +type IsAmbiguity = bool; + impl<'a, Id: Into> ToNameBinding<'a> - for (Module<'a>, ty::Visibility, Span, LocalExpnId) + for (Module<'a>, ty::Visibility, Span, LocalExpnId, IsAmbiguity) { fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> { - arenas.alloc_name_binding(NameBindingData { + let mut binding = NameBindingData { kind: NameBindingKind::Module(self.0), ambiguity: None, warn_ambiguity: false, vis: self.1.to_def_id(), span: self.2, expansion: self.3, - }) + }; + if self.4 { + binding.ambiguity = + Some((arenas.alloc_name_binding(binding.clone()), AmbiguityKind::External)); + } + arenas.alloc_name_binding(binding) } } -impl<'a, Id: Into> ToNameBinding<'a> for (Res, ty::Visibility, Span, LocalExpnId) { +impl<'a, Id: Into> ToNameBinding<'a> + for (Res, ty::Visibility, Span, LocalExpnId, IsAmbiguity) +{ fn to_name_binding(self, arenas: &'a ResolverArenas<'a>) -> NameBinding<'a> { - arenas.alloc_name_binding(NameBindingData { + let mut binding = NameBindingData { kind: NameBindingKind::Res(self.0), ambiguity: None, warn_ambiguity: false, vis: self.1.to_def_id(), span: self.2, expansion: self.3, - }) + }; + if self.4 { + binding.ambiguity = + Some((arenas.alloc_name_binding(binding.clone()), AmbiguityKind::External)); + } + arenas.alloc_name_binding(binding) } } @@ -190,10 +204,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } pub(crate) fn build_reduced_graph_external(&mut self, module: Module<'a>) { - for child in self.tcx.module_children(module.def_id()) { + let def_id = module.def_id(); + for child in self.tcx.module_children(def_id) { let parent_scope = ParentScope::module(module, self); BuildReducedGraphVisitor { r: self, parent_scope } - .build_reduced_graph_for_external_crate_res(child); + .build_reduced_graph_for_external_crate_res(child, false); + } + let children = self.cstore().ambiguity_module_children_untracked(def_id, self.tcx.sess); + for child in &children { + let parent_scope = ParentScope::module(module, self); + BuildReducedGraphVisitor { r: self, parent_scope } + .build_reduced_graph_for_external_crate_res(child, true); } } } @@ -679,7 +700,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { parent.no_implicit_prelude || attr::contains_name(&item.attrs, sym::no_implicit_prelude), ); - self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion, false)); // Descend into the module. self.parent_scope.module = module; @@ -687,13 +708,13 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { // These items live in the value namespace. ItemKind::Static(..) => { - self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion, false)); } ItemKind::Const(..) => { - self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion, false)); } ItemKind::Fn(..) => { - self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, ValueNS, (res, vis, sp, expansion, false)); // Functions introducing procedural macros reserve a slot // in the macro namespace as well (see #52225). @@ -702,7 +723,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { // These items live in the type namespace. ItemKind::TyAlias(..) => { - self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion, false)); } ItemKind::Enum(_, _) => { @@ -713,18 +734,18 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { item.span, parent.no_implicit_prelude, ); - self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion, false)); self.parent_scope.module = module; } ItemKind::TraitAlias(..) => { - self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion, false)); } // These items live in both the type and value namespaces. ItemKind::Struct(ref vdata, _) => { // Define a name in the type namespace. - self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion, false)); // Record field names for error reporting. self.insert_field_def_ids(local_def_id, vdata); @@ -759,7 +780,12 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } let ctor_def_id = self.r.local_def_id(ctor_node_id); let ctor_res = self.res(ctor_def_id); - self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); + self.r.define( + parent, + ident, + ValueNS, + (ctor_res, ctor_vis, sp, expansion, false), + ); self.r.feed_visibility(ctor_def_id, ctor_vis); // We need the field visibility spans also for the constructor for E0603. self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata); @@ -771,7 +797,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } ItemKind::Union(ref vdata, _) => { - self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion, false)); // Record field names for error reporting. self.insert_field_def_ids(local_def_id, vdata); @@ -787,7 +813,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { item.span, parent.no_implicit_prelude, ); - self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion)); + self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion, false)); self.parent_scope.module = module; } @@ -841,7 +867,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { .map(|module| { let used = self.process_macro_use_imports(item, module); let vis = ty::Visibility::::Public; - let binding = (module, vis, sp, expansion).to_name_binding(self.r.arenas); + let binding = (module, vis, sp, expansion, false).to_name_binding(self.r.arenas); (used, Some(ModuleOrUniformRoot::Module(module)), binding) }) .unwrap_or((true, None, self.r.dummy_binding)); @@ -902,7 +928,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { let parent = self.parent_scope.module; let expansion = self.parent_scope.expansion; let vis = self.resolve_visibility(&item.vis); - self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion)); + self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion, false)); self.r.feed_visibility(local_def_id, vis); } @@ -923,9 +949,9 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild) { - let parent = self.parent_scope.module; + fn build_reduced_graph_for_external_crate_res(&mut self, child: &ModChild, ambiguity: bool) { let ModChild { ident, res, vis, ref reexport_chain } = *child; + let parent = self.parent_scope.module; let span = self.r.def_span( reexport_chain .first() @@ -938,7 +964,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { match res { Res::Def(DefKind::Mod | DefKind::Enum | DefKind::Trait, def_id) => { let module = self.r.expect_module(def_id); - self.r.define(parent, ident, TypeNS, (module, vis, span, expansion)); + self.r.define(parent, ident, TypeNS, (module, vis, span, expansion, ambiguity)); } Res::Def( DefKind::Struct @@ -952,7 +978,9 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { _, ) | Res::PrimTy(..) - | Res::ToolMod => self.r.define(parent, ident, TypeNS, (res, vis, span, expansion)), + | Res::ToolMod => { + self.r.define(parent, ident, TypeNS, (res, vis, span, expansion, ambiguity)) + } Res::Def( DefKind::Fn | DefKind::AssocFn @@ -961,9 +989,9 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { | DefKind::AssocConst | DefKind::Ctor(..), _, - ) => self.r.define(parent, ident, ValueNS, (res, vis, span, expansion)), + ) => self.r.define(parent, ident, ValueNS, (res, vis, span, expansion, ambiguity)), Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { - self.r.define(parent, ident, MacroNS, (res, vis, span, expansion)) + self.r.define(parent, ident, MacroNS, (res, vis, span, expansion, ambiguity)) } Res::Def( DefKind::TyParam @@ -1198,7 +1226,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { } else { ty::Visibility::Restricted(CRATE_DEF_ID) }; - let binding = (res, vis, span, expansion).to_name_binding(self.r.arenas); + let binding = (res, vis, span, expansion, false).to_name_binding(self.r.arenas); self.r.set_binding_parent_module(binding, parent_scope.module); self.r.all_macro_rules.insert(ident.name, res); if is_macro_export { @@ -1245,7 +1273,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { if !vis.is_public() { self.insert_unused_macro(ident, def_id, item.id); } - self.r.define(module, ident, MacroNS, (res, vis, span, expansion)); + self.r.define(module, ident, MacroNS, (res, vis, span, expansion, false)); self.r.feed_visibility(def_id, vis); self.parent_scope.macro_rules } @@ -1366,7 +1394,12 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { let parent = self.parent_scope.module; let expansion = self.parent_scope.expansion; - self.r.define(parent, item.ident, ns, (self.res(def_id), vis, item.span, expansion)); + self.r.define( + parent, + item.ident, + ns, + (self.res(def_id), vis, item.span, expansion, false), + ); } visit::walk_assoc_item(self, item, ctxt); @@ -1446,7 +1479,7 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { // Define a name in the type namespace. let def_id = self.r.local_def_id(variant.id); let vis = self.resolve_visibility(&variant.vis); - self.r.define(parent, ident, TypeNS, (self.res(def_id), vis, variant.span, expn_id)); + self.r.define(parent, ident, TypeNS, (self.res(def_id), vis, variant.span, expn_id, false)); self.r.feed_visibility(def_id, vis); // If the variant is marked as non_exhaustive then lower the visibility to within the crate. @@ -1461,7 +1494,12 @@ impl<'a, 'b, 'tcx> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { if let Some(ctor_node_id) = variant.data.ctor_node_id() { let ctor_def_id = self.r.local_def_id(ctor_node_id); let ctor_res = self.res(ctor_def_id); - self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, variant.span, expn_id)); + self.r.define( + parent, + ident, + ValueNS, + (ctor_res, ctor_vis, variant.span, expn_id, false), + ); self.r.feed_visibility(ctor_def_id, ctor_vis); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 57f23200e795a..81564c13eb92d 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -142,12 +142,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { for ambiguity_error in &self.ambiguity_errors { let diag = self.ambiguity_diagnostics(ambiguity_error); if ambiguity_error.warning { - let NameBindingKind::Import { import, .. } = ambiguity_error.b1.0.kind else { - unreachable!() - }; + let root_id = + if let NameBindingKind::Import { import, .. } = ambiguity_error.b1.0.kind { + import.root_id + } else { + assert_eq!(ambiguity_error.kind, AmbiguityKind::External); + CRATE_NODE_ID + }; self.lint_buffer.buffer_lint_with_diagnostic( AMBIGUOUS_GLOB_IMPORTS, - import.root_id, + root_id, ambiguity_error.ident.span, diag.msg.to_string(), BuiltinLintDiagnostics::AmbiguousGlobImports { diag }, @@ -1655,6 +1659,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let (b2_span, b2_note_msg, b2_help_msgs) = could_refer_to(b2, misc2, " also"); AmbiguityErrorDiag { + extern_crate: kind == AmbiguityKind::External, msg: format!("`{ident}` is ambiguous"), span: ident.span, label_span: ident.span, diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 3a31addb10933..f7f9956097040 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -455,6 +455,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Visibility::Public, derive.span, LocalExpnId::ROOT, + false, ) .to_name_binding(this.arenas); result = Ok((binding, Flags::empty())); diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index c5bd7ffa038cd..9d93ac9a2110a 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -19,8 +19,8 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; use rustc_hir::def::{self, DefKind, PartialRes}; -use rustc_middle::metadata::ModChild; use rustc_middle::metadata::Reexport; +use rustc_middle::metadata::{AmbiguityModChild, ModChild}; use rustc_middle::span_bug; use rustc_middle::ty; use rustc_session::lint::builtin::{ @@ -311,8 +311,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } match (old_binding.is_glob_import(), binding.is_glob_import()) { (true, true) => { + let is_ambiguity = binding.is_ambiguity(); // FIXME: remove `!binding.is_ambiguity()` after delete the warning ambiguity. - if !binding.is_ambiguity() + if !is_ambiguity && let NameBindingKind::Import { import: old_import, .. } = old_binding.kind && let NameBindingKind::Import { import, .. } = binding.kind @@ -323,7 +324,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // imported from the same glob-import statement. resolution.binding = Some(binding); } else if res != old_binding.res() { - let binding = if warn_ambiguity { + let binding = if old_binding.is_ambiguity_in_extern_crate() { + // eliminate this ambiguous binding which is defined in the external crate for better compatibility + this.warn_ambiguity(AmbiguityKind::GlobVsGlob, binding, old_binding) + } else if warn_ambiguity { this.warn_ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) } else { this.ambiguity(AmbiguityKind::GlobVsGlob, old_binding, binding) @@ -332,7 +336,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else if !old_binding.vis.is_at_least(binding.vis, this.tcx) { // We are glob-importing the same item but with greater visibility. resolution.binding = Some(binding); - } else if binding.is_ambiguity() { + } else if is_ambiguity { resolution.binding = Some(self.arenas.alloc_name_binding(NameBindingData { warn_ambiguity: true, @@ -1432,19 +1436,28 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(def_id) = module.opt_def_id() { let mut children = Vec::new(); + let mut ambiguity_children = Vec::new(); module.for_each_child(self, |this, ident, _, binding| { let res = binding.res().expect_non_local(); - let error_ambiguity = binding.is_ambiguity() && !binding.warn_ambiguity; - if res != def::Res::Err && !error_ambiguity { + if res != def::Res::Err { let mut reexport_chain = SmallVec::new(); let mut next_binding = binding; while let NameBindingKind::Import { binding, import, .. } = next_binding.kind { reexport_chain.push(import.simplify(this)); next_binding = binding; } - - children.push(ModChild { ident, res, vis: binding.vis, reexport_chain }); + let ambiguity = binding.is_ambiguity() && !binding.warn_ambiguity; + if ambiguity { + ambiguity_children.push(AmbiguityModChild { + ident, + res, + vis: binding.vis, + reexport_chain, + }) + } else { + children.push(ModChild { ident, res, vis: binding.vis, reexport_chain }); + } } }); @@ -1452,6 +1465,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Should be fine because this code is only called for local modules. self.module_children.insert(def_id.expect_local(), children); } + if !ambiguity_children.is_empty() { + self.ambiguity_module_children.insert(def_id.expect_local(), ambiguity_children); + } } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a14f3d494fb4d..5e47d12e0082c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -48,7 +48,7 @@ use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::{PrimTy, TraitCandidate}; use rustc_index::IndexVec; use rustc_metadata::creader::{CStore, CrateLoader}; -use rustc_middle::metadata::ModChild; +use rustc_middle::metadata::{AmbiguityModChild, ModChild}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; use rustc_middle::span_bug; @@ -729,6 +729,7 @@ enum AmbiguityKind { GlobVsGlob, GlobVsExpanded, MoreExpandedVsOuter, + External, } impl AmbiguityKind { @@ -749,6 +750,7 @@ impl AmbiguityKind { AmbiguityKind::MoreExpandedVsOuter => { "a conflict between a macro-expanded name and a less macro-expanded name from outer scope during import or macro resolution" } + AmbiguityKind::External => "multiple glob imports of a name in the same module", // reuse from `GlobVsGlob` } } } @@ -805,6 +807,18 @@ impl<'a> NameBindingData<'a> { } } + fn is_ambiguity_in_extern_crate(&self) -> bool { + if self.ambiguity.is_some_and(|(_, kind)| kind == AmbiguityKind::External) { + true + } else if let NameBindingKind::Import { binding, import, .. } = &self.kind + && import.is_glob() + { + binding.is_ambiguity_in_extern_crate() + } else { + false + } + } + fn is_possibly_imported_variant(&self) -> bool { match self.kind { NameBindingKind::Import { binding, .. } => binding.is_possibly_imported_variant(), @@ -979,6 +993,8 @@ pub struct Resolver<'a, 'tcx> { /// `CrateNum` resolutions of `extern crate` items. extern_crate_map: FxHashMap, module_children: LocalDefIdMap>, + ambiguity_module_children: LocalDefIdMap>, + trait_map: NodeMap>, /// A map from nodes to anonymous modules. @@ -1156,7 +1172,8 @@ impl<'a> ResolverArenas<'a> { if let Some(def_id) = def_id { module_map.insert(def_id, module); let vis = ty::Visibility::::Public; - let binding = (module, vis, module.span, LocalExpnId::ROOT).to_name_binding(self); + let binding = + (module, vis, module.span, LocalExpnId::ROOT, false).to_name_binding(self); module_self_bindings.insert(module, binding); } module @@ -1347,6 +1364,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { extra_lifetime_params_map: Default::default(), extern_crate_map: Default::default(), module_children: Default::default(), + ambiguity_module_children: Default::default(), trait_map: NodeMap::default(), underscore_disambiguator: 0, empty_module, @@ -1366,12 +1384,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { macro_expanded_macro_export_errors: BTreeSet::new(), arenas, - dummy_binding: (Res::Err, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas), + dummy_binding: (Res::Err, pub_vis, DUMMY_SP, LocalExpnId::ROOT, false) + .to_name_binding(arenas), builtin_types_bindings: PrimTy::ALL .iter() .map(|prim_ty| { - let binding = (Res::PrimTy(*prim_ty), pub_vis, DUMMY_SP, LocalExpnId::ROOT) - .to_name_binding(arenas); + let binding = + (Res::PrimTy(*prim_ty), pub_vis, DUMMY_SP, LocalExpnId::ROOT, false) + .to_name_binding(arenas); (prim_ty.name(), binding) }) .collect(), @@ -1380,14 +1400,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .map(|builtin_attr| { let res = Res::NonMacroAttr(NonMacroAttrKind::Builtin(builtin_attr.name)); let binding = - (res, pub_vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(arenas); + (res, pub_vis, DUMMY_SP, LocalExpnId::ROOT, false).to_name_binding(arenas); (builtin_attr.name, binding) }) .collect(), registered_tool_bindings: registered_tools .iter() .map(|ident| { - let binding = (Res::ToolMod, pub_vis, ident.span, LocalExpnId::ROOT) + let binding = (Res::ToolMod, pub_vis, ident.span, LocalExpnId::ROOT, false) .to_name_binding(arenas); (*ident, binding) }) @@ -1519,6 +1539,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { effective_visibilities, extern_crate_map, module_children: self.module_children, + ambiguity_module_children: self.ambiguity_module_children, glob_map, maybe_unused_trait_imports, main_def, @@ -1970,7 +1991,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }; let crate_root = self.expect_module(crate_id.as_def_id()); let vis = ty::Visibility::::Public; - (crate_root, vis, DUMMY_SP, LocalExpnId::ROOT).to_name_binding(self.arenas) + (crate_root, vis, DUMMY_SP, LocalExpnId::ROOT, false).to_name_binding(self.arenas) }) }); diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index fc55481cb0158..5d6511a62bf38 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -404,7 +404,7 @@ impl<'a, 'tcx> ResolverExpand for Resolver<'a, 'tcx> { .iter() .map(|(_, ident)| { let res = Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper); - let binding = (res, Visibility::::Public, ident.span, expn_id) + let binding = (res, Visibility::::Public, ident.span, expn_id, false) .to_name_binding(self.arenas); (*ident, binding) }) diff --git a/tests/ui/imports/ambiguous-4.rs b/tests/ui/imports/ambiguous-4.rs index 24ae33784c526..8e8130a902756 100644 --- a/tests/ui/imports/ambiguous-4.rs +++ b/tests/ui/imports/ambiguous-4.rs @@ -5,5 +5,4 @@ extern crate ambiguous_4_extern; fn main() { ambiguous_4_extern::id(); - // `warning_ambiguous` had been lost at metadata. } diff --git a/tests/ui/imports/auxiliary/glob-conflict-cross-crate-2-extern.rs b/tests/ui/imports/auxiliary/glob-conflict-cross-crate-2-extern.rs new file mode 100644 index 0000000000000..5dec6d4699496 --- /dev/null +++ b/tests/ui/imports/auxiliary/glob-conflict-cross-crate-2-extern.rs @@ -0,0 +1,10 @@ +mod a { + pub type C = i8; +} + +mod b { + pub type C = i16; +} + +pub use a::*; +pub use b::*; diff --git a/tests/ui/imports/auxiliary/issue-114682-2-extern.rs b/tests/ui/imports/auxiliary/issue-114682-2-extern.rs new file mode 100644 index 0000000000000..df2af78916682 --- /dev/null +++ b/tests/ui/imports/auxiliary/issue-114682-2-extern.rs @@ -0,0 +1,17 @@ +macro_rules! m { + () => { + pub fn max() {} + pub(crate) mod max {} + }; +} + +mod d { + m! {} +} + +mod e { + pub type max = i32; +} + +pub use self::d::*; +pub use self::e::*; diff --git a/tests/ui/imports/auxiliary/issue-114682-3-extern.rs b/tests/ui/imports/auxiliary/issue-114682-3-extern.rs new file mode 100644 index 0000000000000..999b66342fe00 --- /dev/null +++ b/tests/ui/imports/auxiliary/issue-114682-3-extern.rs @@ -0,0 +1,16 @@ +mod gio { + pub trait SettingsExt { + fn abc(&self) {} + } + impl SettingsExt for T {} +} + +mod gtk { + pub trait SettingsExt { + fn efg(&self) {} + } + impl SettingsExt for T {} +} + +pub use gtk::*; +pub use gio::*; diff --git a/tests/ui/imports/auxiliary/issue-114682-4-extern.rs b/tests/ui/imports/auxiliary/issue-114682-4-extern.rs new file mode 100644 index 0000000000000..86663f11b31eb --- /dev/null +++ b/tests/ui/imports/auxiliary/issue-114682-4-extern.rs @@ -0,0 +1,10 @@ +mod a { + pub type Result = std::result::Result; +} + +mod b { + pub type Result = std::result::Result; +} + +pub use a::*; +pub use b::*; diff --git a/tests/ui/imports/auxiliary/issue-114682-5-extern-1.rs b/tests/ui/imports/auxiliary/issue-114682-5-extern-1.rs new file mode 100644 index 0000000000000..ebf6493f9f718 --- /dev/null +++ b/tests/ui/imports/auxiliary/issue-114682-5-extern-1.rs @@ -0,0 +1 @@ +pub struct Url; diff --git a/tests/ui/imports/auxiliary/issue-114682-5-extern-2.rs b/tests/ui/imports/auxiliary/issue-114682-5-extern-2.rs new file mode 100644 index 0000000000000..9dbefdd531be3 --- /dev/null +++ b/tests/ui/imports/auxiliary/issue-114682-5-extern-2.rs @@ -0,0 +1,13 @@ +// edition: 2018 +// aux-build: issue-114682-5-extern-1.rs +// compile-flags: --extern issue_114682_5_extern_1 + +pub mod p { + pub use crate::types::*; + pub use crate::*; +} +mod types { + pub mod issue_114682_5_extern_1 {} +} + +pub use issue_114682_5_extern_1; diff --git a/tests/ui/imports/auxiliary/issue-114682-6-extern.rs b/tests/ui/imports/auxiliary/issue-114682-6-extern.rs new file mode 100644 index 0000000000000..caf3c4e35a0e9 --- /dev/null +++ b/tests/ui/imports/auxiliary/issue-114682-6-extern.rs @@ -0,0 +1,9 @@ +mod a { + pub fn log() {} +} +mod b { + pub fn log() {} +} + +pub use self::a::*; +pub use self::b::*; diff --git a/tests/ui/imports/extern-with-ambiguous-2.rs b/tests/ui/imports/extern-with-ambiguous-2.rs index 68c623c1c4a65..fd7877e643f36 100644 --- a/tests/ui/imports/extern-with-ambiguous-2.rs +++ b/tests/ui/imports/extern-with-ambiguous-2.rs @@ -1,4 +1,3 @@ -// check-pass // edition: 2021 // aux-build: extern-with-ambiguous-2-extern.rs @@ -12,5 +11,6 @@ mod s { use s::*; use extern_with_ambiguous_2_extern::*; use error::*; +//~^ ERROR `error` is ambiguous fn main() {} diff --git a/tests/ui/imports/extern-with-ambiguous-2.stderr b/tests/ui/imports/extern-with-ambiguous-2.stderr new file mode 100644 index 0000000000000..2fd66932e4ed2 --- /dev/null +++ b/tests/ui/imports/extern-with-ambiguous-2.stderr @@ -0,0 +1,23 @@ +error[E0659]: `error` is ambiguous + --> $DIR/extern-with-ambiguous-2.rs:13:5 + | +LL | use error::*; + | ^^^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `error` could refer to the module imported here + --> $DIR/extern-with-ambiguous-2.rs:11:5 + | +LL | use s::*; + | ^^^^ + = help: consider adding an explicit import of `error` to disambiguate +note: `error` could also refer to the module imported here + --> $DIR/extern-with-ambiguous-2.rs:12:5 + | +LL | use extern_with_ambiguous_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `error` to disambiguate + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/extern-with-ambiguous-3.rs b/tests/ui/imports/extern-with-ambiguous-3.rs index 282c1d569b0cc..6aea140c77632 100644 --- a/tests/ui/imports/extern-with-ambiguous-3.rs +++ b/tests/ui/imports/extern-with-ambiguous-3.rs @@ -1,4 +1,3 @@ -// check-pass // edition: 2021 // aux-build: extern-with-ambiguous-3-extern.rs // https://github.com/rust-lang/rust/pull/113099#issuecomment-1643974121 @@ -13,5 +12,6 @@ mod s { use s::*; use extern_with_ambiguous_3_extern::*; use error::*; +//~^ ERROR `error` is ambiguous fn main() {} diff --git a/tests/ui/imports/extern-with-ambiguous-3.stderr b/tests/ui/imports/extern-with-ambiguous-3.stderr new file mode 100644 index 0000000000000..95a1175c56b3b --- /dev/null +++ b/tests/ui/imports/extern-with-ambiguous-3.stderr @@ -0,0 +1,23 @@ +error[E0659]: `error` is ambiguous + --> $DIR/extern-with-ambiguous-3.rs:14:5 + | +LL | use error::*; + | ^^^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `error` could refer to the module imported here + --> $DIR/extern-with-ambiguous-3.rs:12:5 + | +LL | use s::*; + | ^^^^ + = help: consider adding an explicit import of `error` to disambiguate +note: `error` could also refer to the module imported here + --> $DIR/extern-with-ambiguous-3.rs:13:5 + | +LL | use extern_with_ambiguous_3_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `error` to disambiguate + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.rs b/tests/ui/imports/glob-conflict-cross-crate-1.rs new file mode 100644 index 0000000000000..9f295a3ba84c2 --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-1.rs @@ -0,0 +1,8 @@ +// aux-build:glob-conflict.rs + +extern crate glob_conflict; + +fn main() { + glob_conflict::f(); //~ ERROR `f` is ambiguous + glob_conflict::glob::f(); //~ ERROR `f` is ambiguous +} diff --git a/tests/ui/imports/glob-conflict-cross-crate-1.stderr b/tests/ui/imports/glob-conflict-cross-crate-1.stderr new file mode 100644 index 0000000000000..6ccd4c7604880 --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-1.stderr @@ -0,0 +1,29 @@ +error[E0659]: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:6:20 + | +LL | glob_conflict::f(); + | ^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:10:9 + | +LL | pub use m1::*; + | ^^ + +error[E0659]: `f` is ambiguous + --> $DIR/glob-conflict-cross-crate-1.rs:7:26 + | +LL | glob_conflict::glob::f(); + | ^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `f` could refer to the function defined here + --> $DIR/auxiliary/glob-conflict.rs:14:13 + | +LL | pub use *; + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.rs b/tests/ui/imports/glob-conflict-cross-crate-2.rs new file mode 100644 index 0000000000000..18b0f620001d1 --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-2.rs @@ -0,0 +1,12 @@ +// check-pass +// aux-build:glob-conflict-cross-crate-2-extern.rs + +extern crate glob_conflict_cross_crate_2_extern; + +use glob_conflict_cross_crate_2_extern::*; + +fn main() { + let _a: C = 1; + //~^ WARNING: `C` is ambiguous + //~| WARNING: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} diff --git a/tests/ui/imports/glob-conflict-cross-crate-2.stderr b/tests/ui/imports/glob-conflict-cross-crate-2.stderr new file mode 100644 index 0000000000000..0ed6c23f89129 --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-2.stderr @@ -0,0 +1,18 @@ +warning: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-2.rs:9:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias defined here + --> $DIR/auxiliary/glob-conflict-cross-crate-2-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.rs b/tests/ui/imports/glob-conflict-cross-crate-3.rs new file mode 100644 index 0000000000000..8e07f8dc7c9cd --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-3.rs @@ -0,0 +1,17 @@ +// check-pass +// aux-build:glob-conflict-cross-crate-2-extern.rs + +extern crate glob_conflict_cross_crate_2_extern; + +mod a { + pub type C = i32; +} + +use glob_conflict_cross_crate_2_extern::*; +use a::*; + +fn main() { + let _a: C = 1; + //~^ WARNING: `C` is ambiguous + //~| WARNING: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +} diff --git a/tests/ui/imports/glob-conflict-cross-crate-3.stderr b/tests/ui/imports/glob-conflict-cross-crate-3.stderr new file mode 100644 index 0000000000000..e019cd333fbda --- /dev/null +++ b/tests/ui/imports/glob-conflict-cross-crate-3.stderr @@ -0,0 +1,25 @@ +warning: `C` is ambiguous + --> $DIR/glob-conflict-cross-crate-3.rs:14:13 + | +LL | let _a: C = 1; + | ^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `C` could refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:11:5 + | +LL | use a::*; + | ^^^^ + = help: consider adding an explicit import of `C` to disambiguate +note: `C` could also refer to the type alias imported here + --> $DIR/glob-conflict-cross-crate-3.rs:10:5 + | +LL | use glob_conflict_cross_crate_2_extern::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `C` to disambiguate + = note: `#[warn(ambiguous_glob_imports)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/glob-conflict-cross-crate.rs b/tests/ui/imports/glob-conflict-cross-crate.rs deleted file mode 100644 index d84c243f2139c..0000000000000 --- a/tests/ui/imports/glob-conflict-cross-crate.rs +++ /dev/null @@ -1,8 +0,0 @@ -// aux-build:glob-conflict.rs - -extern crate glob_conflict; - -fn main() { - glob_conflict::f(); //~ ERROR cannot find function `f` in crate `glob_conflict` - glob_conflict::glob::f(); //~ ERROR cannot find function `f` in module `glob_conflict::glob` -} diff --git a/tests/ui/imports/glob-conflict-cross-crate.stderr b/tests/ui/imports/glob-conflict-cross-crate.stderr deleted file mode 100644 index 0e3b4222fe44f..0000000000000 --- a/tests/ui/imports/glob-conflict-cross-crate.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error[E0425]: cannot find function `f` in crate `glob_conflict` - --> $DIR/glob-conflict-cross-crate.rs:6:20 - | -LL | glob_conflict::f(); - | ^ not found in `glob_conflict` - -error[E0425]: cannot find function `f` in module `glob_conflict::glob` - --> $DIR/glob-conflict-cross-crate.rs:7:26 - | -LL | glob_conflict::glob::f(); - | ^ not found in `glob_conflict::glob` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/imports/issue-114682-1.rs b/tests/ui/imports/issue-114682-1.rs new file mode 100644 index 0000000000000..88fe05e51444d --- /dev/null +++ b/tests/ui/imports/issue-114682-1.rs @@ -0,0 +1,25 @@ +// https://github.com/rust-lang/rust/pull/114682#discussion_r1420534109 + +#![feature(decl_macro)] + +macro_rules! mac { + () => { + pub macro A() { + println!("non import") + } + } +} + +mod m { + pub macro A() { + println!("import") + } +} + +pub use m::*; +mac!(); + +fn main() { + A!(); + //~^ ERROR `A` is ambiguous +} diff --git a/tests/ui/imports/issue-114682-1.stderr b/tests/ui/imports/issue-114682-1.stderr new file mode 100644 index 0000000000000..85fb7f7919e4e --- /dev/null +++ b/tests/ui/imports/issue-114682-1.stderr @@ -0,0 +1,28 @@ +error[E0659]: `A` is ambiguous + --> $DIR/issue-114682-1.rs:23:5 + | +LL | A!(); + | ^ ambiguous name + | + = 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: `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 +note: `A` could also refer to the macro imported here + --> $DIR/issue-114682-1.rs:19:9 + | +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 + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/issue-114682-2.rs b/tests/ui/imports/issue-114682-2.rs new file mode 100644 index 0000000000000..8c71ae582e2ba --- /dev/null +++ b/tests/ui/imports/issue-114682-2.rs @@ -0,0 +1,9 @@ +// aux-build: issue-114682-2-extern.rs + +// https://github.com/rust-lang/rust/pull/114682#issuecomment-1879998900 +extern crate issue_114682_2_extern; + +use issue_114682_2_extern::max; +//~^ ERROR: `max` is ambiguous + +fn main() {} diff --git a/tests/ui/imports/issue-114682-2.stderr b/tests/ui/imports/issue-114682-2.stderr new file mode 100644 index 0000000000000..9efb9811a5691 --- /dev/null +++ b/tests/ui/imports/issue-114682-2.stderr @@ -0,0 +1,16 @@ +error[E0659]: `max` is ambiguous + --> $DIR/issue-114682-2.rs:6:28 + | +LL | use issue_114682_2_extern::max; + | ^^^ ambiguous name + | + = note: ambiguous because of multiple glob imports of a name in the same module +note: `max` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-2-extern.rs:17:9 + | +LL | pub use self::e::*; + | ^^^^^^^ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0659`. diff --git a/tests/ui/imports/issue-114682-3.rs b/tests/ui/imports/issue-114682-3.rs new file mode 100644 index 0000000000000..28a895e693db7 --- /dev/null +++ b/tests/ui/imports/issue-114682-3.rs @@ -0,0 +1,23 @@ +// check-pass +// aux-build: issue-114682-3-extern.rs + +// https://github.com/rust-lang/rust/pull/114682#issuecomment-1880625909 +extern crate issue_114682_3_extern; + +use issue_114682_3_extern::*; + +mod auto { + pub trait SettingsExt { + fn ext(&self) {} + } + + impl SettingsExt for T {} +} + +pub use self::auto::*; +//~^ WARNING ambiguous glob re-exports + +pub fn main() { + let a: u8 = 1; + a.ext(); +} diff --git a/tests/ui/imports/issue-114682-3.stderr b/tests/ui/imports/issue-114682-3.stderr new file mode 100644 index 0000000000000..5d4c2e75e476f --- /dev/null +++ b/tests/ui/imports/issue-114682-3.stderr @@ -0,0 +1,13 @@ +warning: ambiguous glob re-exports + --> $DIR/issue-114682-3.rs:17:9 + | +LL | use issue_114682_3_extern::*; + | ------------------------ but the name `SettingsExt` in the type namespace is also re-exported here +... +LL | pub use self::auto::*; + | ^^^^^^^^^^^^^ the name `SettingsExt` in the type namespace is first re-exported here + | + = note: `#[warn(ambiguous_glob_reexports)]` on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/issue-114682-4.rs b/tests/ui/imports/issue-114682-4.rs new file mode 100644 index 0000000000000..10cf43a70e900 --- /dev/null +++ b/tests/ui/imports/issue-114682-4.rs @@ -0,0 +1,15 @@ +// aux-build: issue-114682-4-extern.rs + +// https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 +extern crate issue_114682_4_extern; + +use issue_114682_4_extern::*; + +fn a() -> Result { + //~^ WARN: `Result` is ambiguous + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + //~| ERROR: type alias takes 1 generic argument but 2 generic arguments were supplied + Ok(1) +} + +pub fn main() {} diff --git a/tests/ui/imports/issue-114682-4.stderr b/tests/ui/imports/issue-114682-4.stderr new file mode 100644 index 0000000000000..52cee0259e24a --- /dev/null +++ b/tests/ui/imports/issue-114682-4.stderr @@ -0,0 +1,33 @@ +warning: `Result` is ambiguous + --> $DIR/issue-114682-4.rs:8:11 + | +LL | fn a() -> Result { + | ^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `Result` could refer to the type alias defined here + --> $DIR/auxiliary/issue-114682-4-extern.rs:9:9 + | +LL | pub use a::*; + | ^ + = note: `#[warn(ambiguous_glob_imports)]` on by default + +error[E0107]: type alias takes 1 generic argument but 2 generic arguments were supplied + --> $DIR/issue-114682-4.rs:8:11 + | +LL | fn a() -> Result { + | ^^^^^^ -- help: remove this generic argument + | | + | expected 1 generic argument + | +note: type alias defined here, with 1 generic parameter: `T` + --> $DIR/auxiliary/issue-114682-4-extern.rs:2:14 + | +LL | pub type Result = std::result::Result; + | ^^^^^^ - + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/imports/issue-114682-5.rs b/tests/ui/imports/issue-114682-5.rs new file mode 100644 index 0000000000000..dc9c7782d1373 --- /dev/null +++ b/tests/ui/imports/issue-114682-5.rs @@ -0,0 +1,16 @@ +// edition: 2018 +// aux-build: issue-114682-5-extern-1.rs +// aux-build: issue-114682-5-extern-2.rs +// compile-flags: --extern issue_114682_5_extern_1 + +// https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 +extern crate issue_114682_5_extern_2; + +use issue_114682_5_extern_2::p::*; +use issue_114682_5_extern_1::Url; +//~^ WARN: `issue_114682_5_extern_1` is ambiguous +//~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! +//~| ERROR: unresolved import `issue_114682_5_extern_1::Url` +//~| ERROR: `issue_114682_5_extern_1` is ambiguous + +fn main() {} diff --git a/tests/ui/imports/issue-114682-5.stderr b/tests/ui/imports/issue-114682-5.stderr new file mode 100644 index 0000000000000..7a7de5793bc40 --- /dev/null +++ b/tests/ui/imports/issue-114682-5.stderr @@ -0,0 +1,48 @@ +error[E0432]: unresolved import `issue_114682_5_extern_1::Url` + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `Url` in `types::issue_114682_5_extern_1` + | +help: consider importing this struct instead + | +LL | use ::issue_114682_5_extern_1::Url; + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +error[E0659]: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = note: ambiguous because of a conflict between a name from a glob import and an outer scope during import or macro resolution + = note: `issue_114682_5_extern_1` could refer to a crate passed with `--extern` + = help: use `::issue_114682_5_extern_1` to refer to this crate unambiguously +note: `issue_114682_5_extern_1` could also refer to the module imported here + --> $DIR/issue-114682-5.rs:9:5 + | +LL | use issue_114682_5_extern_2::p::*; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = help: consider adding an explicit import of `issue_114682_5_extern_1` to disambiguate + = help: or use `crate::issue_114682_5_extern_1` to refer to this module unambiguously + +warning: `issue_114682_5_extern_1` is ambiguous + --> $DIR/issue-114682-5.rs:10:5 + | +LL | use issue_114682_5_extern_1::Url; + | ^^^^^^^^^^^^^^^^^^^^^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `issue_114682_5_extern_1` could refer to the module defined here + --> $DIR/auxiliary/issue-114682-5-extern-2.rs:6:13 + | +LL | pub use crate::types::*; + | ^^^^^^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` on by default + +error: aborting due to 2 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0432, E0659. +For more information about an error, try `rustc --explain E0432`. diff --git a/tests/ui/imports/issue-114682-6.rs b/tests/ui/imports/issue-114682-6.rs new file mode 100644 index 0000000000000..05637654cdf77 --- /dev/null +++ b/tests/ui/imports/issue-114682-6.rs @@ -0,0 +1,14 @@ +// check-pass +// aux-build: issue-114682-6-extern.rs + +// https://github.com/rust-lang/rust/pull/114682#issuecomment-1880755441 +extern crate issue_114682_6_extern; + +use issue_114682_6_extern::*; + +fn main() { + let log = 2; + //~^ WARN: `log` is ambiguous + //~| WARN: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + let _ = log; +} diff --git a/tests/ui/imports/issue-114682-6.stderr b/tests/ui/imports/issue-114682-6.stderr new file mode 100644 index 0000000000000..a5a70763f6279 --- /dev/null +++ b/tests/ui/imports/issue-114682-6.stderr @@ -0,0 +1,18 @@ +warning: `log` is ambiguous + --> $DIR/issue-114682-6.rs:10:9 + | +LL | let log = 2; + | ^^^ ambiguous name + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #114095 + = note: ambiguous because of multiple glob imports of a name in the same module +note: `log` could refer to the function defined here + --> $DIR/auxiliary/issue-114682-6-extern.rs:8:9 + | +LL | pub use self::a::*; + | ^^^^^^^ + = note: `#[warn(ambiguous_glob_imports)]` on by default + +warning: 1 warning emitted +