From 73ed27196b4bf05c3810be5c4113da2b45662b24 Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Mon, 20 Jul 2026 12:47:25 +0200 Subject: [PATCH] When recording traits, if a decl is ambiguous we make sure to record at least 1 trait of the ambiguous decls (is possible) such that we can record the `ambiguously_glob_imported_trait` lint. Also updated the issue linked by the lint. + added extra test + bless original test because of updated link --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 31 +++++++++++---- .../ambiguous-trait-and-struct-in-scope.rs | 39 +++++++++++++++++++ ...ambiguous-trait-and-struct-in-scope.stderr | 16 ++++++++ .../imports/ambiguous-trait-in-scope.stderr | 14 +++---- 5 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs create mode 100644 tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 75d8d3d129278..44af1ac961e2f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4560,7 +4560,7 @@ declare_lint! { Warn, "detects uses of ambiguously glob imported traits", @future_incompatible = FutureIncompatibleInfo { - reason: fcw!(FutureReleaseError #147992), + reason: fcw!(FutureReleaseError #152822), report_in_deps: false, }; } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index a1c3ed5a068f8..ae84e3cf2d86c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -806,17 +806,32 @@ impl<'ra> Module<'ra> { let mut traits = self.traits.borrow_mut(resolver.as_ref()); if traits.is_none() { let mut collected_traits = Vec::new(); - self.for_each_child(resolver, |r, ident, _, ns, binding| { + self.for_each_child(resolver, |r, ident, _, ns, mut decl| { if ns != TypeNS { return; } - if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() { - collected_traits.push(( - ident.name, - binding, - r.as_ref().get_module(def_id), - binding.is_ambiguity_recursive(), - )); + + let ambiguous = decl.is_ambiguity_recursive(); + let mut try_record_trait = |decl: Decl<'ra>| { + if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = decl.res() { + collected_traits.push(( + ident.name, + decl, + r.as_ref().get_module(def_id), + ambiguous, + )); + true + } else { + false + } + }; + // Try to record at least one trait if the decl is ambiguous, such that we can + // report the `ambiguous_glob_imported_traits` lint. Otherwise we would report an + // error that the trait is not found. + while !try_record_trait(decl) + && let Some((_, ambig_decl)) = decl.descent_to_ambiguity() + { + decl = ambig_decl; } }); *traits = Some(collected_traits.into_boxed_slice()); diff --git a/tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs new file mode 100644 index 0000000000000..ec1ea313302d6 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs @@ -0,0 +1,39 @@ +//@ check-pass +//@ edition:2018 +// +// Tests that when the primary declaration is not a trait but the ambiguous declaration is, +// the ambiguous trait is still recorded among the module's traits. This is to make sure +// that we can report the `ambiguously_glob_import_trait` lint. +// +// Test case is from #159476. + +mod module_1 { + mod nested_1 { + pub struct Foo; + } + + pub use nested_1::Foo; +} + +mod module_2 { + // same name as the struct + pub trait Foo: Sized { + fn method(self) {} + } + impl Foo for i32 {} +} + +mod module_3 { + mod nested_3 { + use super::*; + use crate::module_2::*; + fn weird() { + 1_i32.method(); //~ WARNING Use of ambiguously glob imported trait `Foo` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + } + } + + use crate::module_1::*; +} + +fn main() {} diff --git a/tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr new file mode 100644 index 0000000000000..540d41fb65f22 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr @@ -0,0 +1,16 @@ +warning: Use of ambiguously glob imported trait `Foo` + --> $DIR/ambiguous-trait-and-struct-in-scope.rs:31:19 + | +LL | use crate::module_2::*; + | --------------- `Foo` imported ambiguously here +LL | fn weird() { +LL | 1_i32.method(); + | ^^^^^^ + | + = help: Import `Foo` explicitly + = 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 #152822 + = note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/ambiguous-trait-in-scope.stderr b/tests/ui/imports/ambiguous-trait-in-scope.stderr index 9360e104bf24f..0b37ab0c9d609 100644 --- a/tests/ui/imports/ambiguous-trait-in-scope.stderr +++ b/tests/ui/imports/ambiguous-trait-in-scope.stderr @@ -9,7 +9,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = 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 #147992 + = note: for more information, see issue #152822 = note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default error[E0599]: no method named `method2` found for type `u8` in the current scope @@ -51,7 +51,7 @@ LL | 0u8.method2(); | = help: Import `Trait` explicitly = 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 #147992 + = note: for more information, see issue #152822 warning: Use of ambiguously glob imported trait `Trait` --> $DIR/ambiguous-trait-in-scope.rs:49:9 @@ -64,7 +64,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = 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 #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:51:9 @@ -90,7 +90,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = 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 #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:58:9 @@ -117,7 +117,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = 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 #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:66:9 @@ -144,7 +144,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = 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 #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:74:9 @@ -170,7 +170,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = 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 #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:81:9