From 576dc67dd5a21db702e350842dca98a341248fa6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 14 Nov 2025 14:27:12 +0300 Subject: [PATCH] resolve: Consider traits from shadowed glob imports to be in scope --- compiler/rustc_resolve/src/lib.rs | 24 ++++++++++------- .../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 ------------- 5 files changed, 34 insertions(+), 49 deletions(-) delete mode 100644 tests/ui/shadowed/shadowed-trait-methods.stderr diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 7ce70ee9af8d4..c669e8456f329 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -702,18 +702,24 @@ impl<'ra> Module<'ra> { } /// This modifies `self` in place. The traits will be stored in `self.traits`. - fn ensure_traits<'tcx>(self, resolver: &impl AsRef>) { - let mut traits = self.traits.borrow_mut(resolver.as_ref()); + fn ensure_traits<'tcx>(self, resolver: &Resolver<'ra, 'tcx>) { + let mut traits = self.traits.borrow_mut(resolver); if traits.is_none() { let mut collected_traits = Vec::new(); - self.for_each_child(resolver, |r, name, ns, binding| { - if ns != TypeNS { - return; - } - if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() { - collected_traits.push((name, binding, r.as_ref().get_module(def_id))) + for (key, entry) in resolver.resolutions(self).borrow().iter() { + if key.ns == TypeNS { + let entry = entry.borrow(); + for binding in [entry.non_glob_binding, entry.glob_binding] { + if let Some(binding) = binding + && let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = + binding.res() + { + collected_traits.push((key.ident, binding, resolver.get_module(def_id))) + } + } } - }); + } + *traits = Some(collected_traits.into_boxed_slice()); } } 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`.