From 4925e53cdbc081d160cea669fc9d5ad0e132bd41 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 14 Nov 2025 15:38:23 +0300 Subject: [PATCH] resolve: Consider all traits from ambiguous glob imports to be in scope --- compiler/rustc_resolve/src/imports.rs | 18 ++++- tests/ui/imports/ambiguous-trait-in-scope.rs | 78 +++++++++++++++++++ .../auxiliary/ambiguous-trait-reexport.rs | 23 ++++++ tests/ui/macros/macro-context.stderr | 2 +- .../future-prelude-collision-shadow.rs | 8 +- .../future-prelude-collision-shadow.stderr | 27 +++---- tests/ui/shadowed/shadowed-trait-methods.rs | 6 +- .../ui/shadowed/shadowed-trait-methods.stderr | 18 ----- 8 files changed, 138 insertions(+), 42 deletions(-) create mode 100644 tests/ui/imports/ambiguous-trait-in-scope.rs create mode 100644 tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs delete mode 100644 tests/ui/shadowed/shadowed-trait-methods.stderr diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index f98aaecea18ce..ad8cb6fc87f76 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -433,7 +433,23 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } Ok(()) - }) + })?; + + if ident.name != kw::Underscore + && binding.is_glob_import() + && matches!(binding.res(), Res::Def(DefKind::Trait | DefKind::TraitAlias, _)) + { + self.try_define_local( + module, + Ident::new(kw::Underscore, ident.span), + TypeNS, + binding, + false, + ) + .expect("tralala"); + } + + Ok(()) } fn new_ambiguity_binding( diff --git a/tests/ui/imports/ambiguous-trait-in-scope.rs b/tests/ui/imports/ambiguous-trait-in-scope.rs new file mode 100644 index 0000000000000..3aa1b5ba65d75 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-in-scope.rs @@ -0,0 +1,78 @@ +//@ check-pass +//@ edition:2018 +//@ aux-crate:external=ambiguous-trait-reexport.rs + +mod m1 { + pub trait Trait { + fn method1(&self) {} + } + impl Trait for u8 {} +} +mod m2 { + pub trait Trait { + fn method2(&self) {} + } + impl Trait for u8 {} +} +mod m1_reexport { + pub use crate::m1::Trait; +} +mod m2_reexport { + pub use crate::m2::Trait; +} + +mod ambig_reexport { + pub use crate::m1::*; + pub use crate::m2::*; +} + +fn test1() { + // Create an ambiguous import for `Trait` in one order + use m1::*; + use m2::*; + 0u8.method1(); + 0u8.method2(); +} + +fn test2() { + // Create an ambiguous import for `Trait` in another order + use m1::*; + use m2::*; + 0u8.method1(); + 0u8.method2(); +} + +fn test_indirect_reexport() { + use m1_reexport::*; + use m2_reexport::*; + 0u8.method1(); + 0u8.method2(); +} + +fn test_ambig_reexport() { + use ambig_reexport::*; + 0u8.method1(); + 0u8.method2(); +} + +fn test_external() { + use external::m1::*; + use external::m2::*; + 0u8.method1(); + 0u8.method2(); +} + +fn test_external_indirect_reexport() { + use external::m1_reexport::*; + use external::m2_reexport::*; + 0u8.method1(); + 0u8.method2(); +} + +fn test_external_ambig_reexport() { + use external::ambig_reexport::*; + 0u8.method1(); + 0u8.method2(); +} + +fn main() {} diff --git a/tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs b/tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs new file mode 100644 index 0000000000000..77fb0c7d39348 --- /dev/null +++ b/tests/ui/imports/auxiliary/ambiguous-trait-reexport.rs @@ -0,0 +1,23 @@ +pub mod m1 { + pub trait Trait { + fn method1(&self) {} + } + impl Trait for u8 {} +} +pub mod m2 { + pub trait Trait { + fn method2(&self) {} + } + impl Trait for u8 {} +} +pub mod m1_reexport { + pub use crate::m1::Trait; +} +pub mod m2_reexport { + pub use crate::m2::Trait; +} + +pub mod ambig_reexport { + pub use crate::m1::*; + pub use crate::m2::*; +} diff --git a/tests/ui/macros/macro-context.stderr b/tests/ui/macros/macro-context.stderr index 2efc0b136bc14..22f9a1b52c395 100644 --- a/tests/ui/macros/macro-context.stderr +++ b/tests/ui/macros/macro-context.stderr @@ -46,7 +46,7 @@ error[E0412]: cannot find type `i` in this scope --> $DIR/macro-context.rs:3:13 | LL | () => ( i ; typeof ); - | ^ help: a builtin type with a similar name exists: `i8` + | ^ not found in this scope ... LL | let a: m!(); | ---- in this macro invocation diff --git a/tests/ui/rust-2021/future-prelude-collision-shadow.rs b/tests/ui/rust-2021/future-prelude-collision-shadow.rs index 556d646e0131b..ad7bdfbddf049 100644 --- a/tests/ui/rust-2021/future-prelude-collision-shadow.rs +++ b/tests/ui/rust-2021/future-prelude-collision-shadow.rs @@ -1,4 +1,6 @@ +//@ check-pass //@ edition:2018 + #![warn(rust_2021_prelude_collisions)] #![allow(dead_code)] #![allow(unused_imports)] @@ -22,10 +24,10 @@ mod d { use crate::m::*; fn main() { - // Here, `TryIntoU32` is imported but shadowed, but in that case we don't permit its methods - // to be available. + // Here, `TryIntoU32` is imported and shadowed, but its methods are still available. let _: u32 = 3u8.try_into().unwrap(); - //~^ ERROR no method named `try_into` found for type `u8` in the current scope + //~^ WARN trait method `try_into` will become ambiguous in Rust 2021 + //~| WARN this is accepted in the current edition } } diff --git a/tests/ui/rust-2021/future-prelude-collision-shadow.stderr b/tests/ui/rust-2021/future-prelude-collision-shadow.stderr index 966613e12b50c..9cdcb63986ed3 100644 --- a/tests/ui/rust-2021/future-prelude-collision-shadow.stderr +++ b/tests/ui/rust-2021/future-prelude-collision-shadow.stderr @@ -1,23 +1,16 @@ -error[E0599]: no method named `try_into` found for type `u8` in the current scope - --> $DIR/future-prelude-collision-shadow.rs:27:26 +warning: trait method `try_into` will become ambiguous in Rust 2021 + --> $DIR/future-prelude-collision-shadow.rs:28:22 | LL | let _: u32 = 3u8.try_into().unwrap(); - | ^^^^^^^^ + | ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)` | - = help: items from traits can only be used if the trait is in scope - = note: 'std::convert::TryInto' is included in the prelude starting in Edition 2021 -help: the following traits which provide `try_into` are implemented but not in scope; perhaps you want to import one of them - | -LL + use crate::m::TryIntoU32; - | -LL + use std::convert::TryInto; - | -help: there is a method `into` with a similar name - | -LL - let _: u32 = 3u8.try_into().unwrap(); -LL + let _: u32 = 3u8.into().unwrap(); + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see +note: the lint level is defined here + --> $DIR/future-prelude-collision-shadow.rs:4:9 | +LL | #![warn(rust_2021_prelude_collisions)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 1 previous error +warning: 1 warning emitted -For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/shadowed/shadowed-trait-methods.rs b/tests/ui/shadowed/shadowed-trait-methods.rs index 6cc5159fd0896..2626c0a02eed8 100644 --- a/tests/ui/shadowed/shadowed-trait-methods.rs +++ b/tests/ui/shadowed/shadowed-trait-methods.rs @@ -1,4 +1,6 @@ -// Test that methods from shadowed traits cannot be used +// Test that methods from shadowed traits can be used + +//@ check-pass mod foo { pub trait T { fn f(&self) {} } @@ -10,5 +12,5 @@ mod bar { pub use crate::foo::T; } fn main() { pub use bar::*; struct T; - ().f() //~ ERROR no method + ().f() // OK } diff --git a/tests/ui/shadowed/shadowed-trait-methods.stderr b/tests/ui/shadowed/shadowed-trait-methods.stderr deleted file mode 100644 index 2c990fababf9f..0000000000000 --- a/tests/ui/shadowed/shadowed-trait-methods.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0599]: no method named `f` found for unit type `()` in the current scope - --> $DIR/shadowed-trait-methods.rs:13:8 - | -LL | pub trait T { fn f(&self) {} } - | - the method is available for `()` here -... -LL | ().f() - | ^ method not found in `()` - | - = help: items from traits can only be used if the trait is in scope -help: trait `T` which provides `f` is implemented but not in scope; perhaps you want to import it - | -LL + use foo::T; - | - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0599`.