From 5b1070b040080af3b8d6d916ca34c598b435fd7e Mon Sep 17 00:00:00 2001 From: xonx4l Date: Sat, 27 Dec 2025 14:41:19 +0530 Subject: [PATCH 01/10] Add note for param-env shadowing --- .../src/error_reporting/infer/mod.rs | 65 ++++++++++++++++++- .../param-env-shadowing-issue-149910.rs | 14 ++++ .../param-env-shadowing-issue-149910.stderr | 21 ++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 tests/ui/associated-types/param-env-shadowing-issue-149910.rs create mode 100644 tests/ui/associated-types/param-env-shadowing-issue-149910.stderr diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 47810e2578df6..cfe5b1f425563 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -149,11 +149,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { actual: Ty<'tcx>, err: TypeError<'tcx>, ) -> Diag<'a> { - self.report_and_explain_type_error( + let mut diag = self.report_and_explain_type_error( TypeTrace::types(cause, expected, actual), param_env, err, - ) + ); + + self.suggest_param_env_shadowing(&mut diag, expected, actual); + + diag } pub fn report_mismatched_consts( @@ -240,6 +244,63 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { false } + fn suggest_param_env_shadowing( + &self, + diag: &mut Diag<'_>, + expected: Ty<'tcx>, + found: Ty<'tcx>, + ) { + let (alias, concrete) = match (expected.kind(), found.kind()) { + (ty::Alias(ty::Projection, proj), _) => (proj, found), + (_, ty::Alias(ty::Projection, proj)) => (proj, expected), + _ => return, + }; + + let tcx = self.tcx; + let trait_def_id = alias.trait_def_id(tcx); + let impls = tcx.trait_impls_of(trait_def_id); + + let all_impls = + impls.blanket_impls().iter().chain(impls.non_blanket_impls().values().flatten()); + + for &impl_def_id in all_impls { + let is_shadowed = self.infcx.probe(|_| { + let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); + + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs); + + let expected_trait_ref = alias.trait_ref(tcx); + + if self.infcx.can_eq(ty::ParamEnv::empty(), expected_trait_ref, impl_trait_ref) { + let name = tcx.item_name(alias.def_id); + let assoc_item = tcx + .associated_items(impl_def_id) + .filter_by_name_unhygienic(name) + .find(|item| matches!(item.kind, ty::AssocKind::Type { .. })); + + if let Some(item) = assoc_item { + let impl_assoc_ty = tcx.type_of(item.def_id).instantiate(tcx, impl_substs); + if self.infcx.can_eq(ty::ParamEnv::empty(), impl_assoc_ty, concrete) { + return true; + } + } + } + false + }); + + if is_shadowed { + diag.note(format!( + "the associated type `{}` is defined as `{}` in the implementation, \ + but the generic bound `{}` hides this definition", + self.ty_to_string(tcx.mk_ty_from_kind(ty::Alias(ty::Projection, *alias))), + self.ty_to_string(concrete), + self.ty_to_string(alias.self_ty()) + )); + return; + } + } + } + fn note_error_origin( &self, err: &mut Diag<'_>, diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.rs b/tests/ui/associated-types/param-env-shadowing-issue-149910.rs new file mode 100644 index 0000000000000..bd4df859dc074 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.rs @@ -0,0 +1,14 @@ +trait Trait { + type Assoc; +} + +impl Trait for T { + type Assoc = T; +} + +fn foo(x: T) -> T::Assoc { + x + //~^ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr new file mode 100644 index 0000000000000..57eaaee9906b3 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr @@ -0,0 +1,21 @@ +error[E0308]: mismatched types + --> $DIR/issue-149910.rs:10:5 + | +LL | fn foo(x: T) -> T::Assoc { + | - -------- expected `::Assoc` because of return type + | | + | found this type parameter +LL | x + | ^ expected associated type, found type parameter `T` + | + = note: expected associated type `::Assoc` + found type parameter `T` + = note: the associated type `::Assoc` is defined as `T` in the implementation, but the generic bound `T` hides this definition +help: consider further restricting this bound + | +LL | fn foo>(x: T) -> T::Assoc { + | +++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From a873a3fe778950dfae31220525063174b0358889 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Sun, 11 Jan 2026 18:42:52 +0000 Subject: [PATCH 02/10] add suggested changes --- .../src/error_reporting/infer/mod.rs | 54 +++++++++++-------- .../rustc_trait_selection/src/traits/mod.rs | 2 +- ...g-assoc-type-because-of-assoc-const.stderr | 1 + .../defaults-specialization.stderr | 4 ++ .../param-env-shadowing-issue-149910.stderr | 4 +- ...lization-default-projection.current.stderr | 2 + ...cialization-default-projection.next.stderr | 2 + ...pecialization-default-types.current.stderr | 2 + .../specialization-default-types.next.stderr | 2 + 9 files changed, 48 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index cfe5b1f425563..86cec9f647b70 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -72,12 +72,17 @@ use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Pos, Span, sym}; use tracing::{debug, instrument}; use crate::error_reporting::TypeErrCtxt; +use crate::error_reporting::traits::ambiguity::{ + CandidateSource, compute_applicable_impls_for_diagnostics, +}; use crate::errors::{ObligationCauseFailureCode, TypeErrorAdditionalDiags}; use crate::infer; use crate::infer::relate::{self, RelateResult, TypeRelation}; use crate::infer::{InferCtxt, InferCtxtExt as _, TypeTrace, ValuePairs}; use crate::solve::deeply_normalize_for_diagnostics; -use crate::traits::{MatchExpressionArmCause, ObligationCause, ObligationCauseCode}; +use crate::traits::{ + MatchExpressionArmCause, Obligation, ObligationCause, ObligationCauseCode, specialization_graph, +}; mod note_and_explain; mod suggest; @@ -155,7 +160,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { err, ); - self.suggest_param_env_shadowing(&mut diag, expected, actual); + self.suggest_param_env_shadowing(&mut diag, expected, actual, param_env); diag } @@ -249,6 +254,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { diag: &mut Diag<'_>, expected: Ty<'tcx>, found: Ty<'tcx>, + param_env: ty::ParamEnv<'tcx>, ) { let (alias, concrete) = match (expected.kind(), found.kind()) { (ty::Alias(ty::Projection, proj), _) => (proj, found), @@ -257,35 +263,39 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let tcx = self.tcx; - let trait_def_id = alias.trait_def_id(tcx); - let impls = tcx.trait_impls_of(trait_def_id); - let all_impls = - impls.blanket_impls().iter().chain(impls.non_blanket_impls().values().flatten()); + let trait_ref = alias.trait_ref(tcx); + let obligation = + Obligation::new(tcx, ObligationCause::dummy(), param_env, ty::Binder::dummy(trait_ref)); + + let applicable_impls = compute_applicable_impls_for_diagnostics(self.infcx, &obligation); + + for candidate in applicable_impls { + let impl_def_id = match candidate { + CandidateSource::DefId(did) => did, + CandidateSource::ParamEnv(_) => continue, + }; - for &impl_def_id in all_impls { let is_shadowed = self.infcx.probe(|_| { let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs); let expected_trait_ref = alias.trait_ref(tcx); - if self.infcx.can_eq(ty::ParamEnv::empty(), expected_trait_ref, impl_trait_ref) { - let name = tcx.item_name(alias.def_id); - let assoc_item = tcx - .associated_items(impl_def_id) - .filter_by_name_unhygienic(name) - .find(|item| matches!(item.kind, ty::AssocKind::Type { .. })); - - if let Some(item) = assoc_item { - let impl_assoc_ty = tcx.type_of(item.def_id).instantiate(tcx, impl_substs); - if self.infcx.can_eq(ty::ParamEnv::empty(), impl_assoc_ty, concrete) { - return true; - } - } + if !self.infcx.can_eq(param_env, expected_trait_ref, impl_trait_ref) { + return false; } - false + + let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id) + { + Ok(leaf) => leaf, + Err(_) => return false, + }; + + let impl_item_def_id = leaf_def.item.def_id; + let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, impl_substs); + + self.infcx.can_eq(param_env, impl_assoc_ty, concrete) }); if is_shadowed { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 08f1d947dfb5c..1fde7e5d43b76 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -16,7 +16,7 @@ pub mod project; pub mod query; #[allow(hidden_glob_reexports)] mod select; -mod specialize; +pub mod specialize; mod structural_normalize; #[allow(hidden_glob_reexports)] mod util; diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr index 21bc37bb3ea2d..af0db3a95993f 100644 --- a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr +++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr @@ -6,6 +6,7 @@ LL | const N: C::M = 4u8; | = note: expected associated type `::M` found type `u8` + = note: the associated type `::M` is defined as `u8` in the implementation, but the generic bound `C` hides this definition help: consider constraining the associated type `::M` to `u8` | LL | impl> U for u16 { diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index 7d19ac85982a3..be0e178e40315 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -75,6 +75,7 @@ LL | fn make() -> Self::Ty { 0u8 } found type `u8` = help: consider constraining the associated type ` as Tr>::Ty` to `u8` or calling a method that returns ` as Tr>::Ty` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type ` as Tr>::Ty` is defined as `u8` in the implementation, but the generic bound `A2` hides this definition error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:44:29 @@ -89,6 +90,7 @@ LL | fn make() -> Self::Ty { true } | = note: expected associated type ` as Tr>::Ty` found type `bool` + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the generic bound `B2` hides this definition error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:87:32 @@ -121,6 +123,7 @@ help: a method is available that returns ` as Tr>::Ty` | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the generic bound `B<()>` hides this definition error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:89:33 @@ -153,6 +156,7 @@ help: a method is available that returns ` as Tr>::Ty` | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the generic bound `B2<()>` hides this definition error: aborting due to 9 previous errors; 1 warning emitted diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr index 57eaaee9906b3..fb05f0add349d 100644 --- a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr @@ -1,11 +1,11 @@ error[E0308]: mismatched types - --> $DIR/issue-149910.rs:10:5 + --> $DIR/param-env-shadowing-issue-149910.rs:10:5 | LL | fn foo(x: T) -> T::Assoc { | - -------- expected `::Assoc` because of return type | | | found this type parameter -LL | x +LL | x | ^ expected associated type, found type parameter `T` | = note: expected associated type `::Assoc` diff --git a/tests/ui/specialization/specialization-default-projection.current.stderr b/tests/ui/specialization/specialization-default-projection.current.stderr index 038c379c43e13..c50b053cf2dc1 100644 --- a/tests/ui/specialization/specialization-default-projection.current.stderr +++ b/tests/ui/specialization/specialization-default-projection.current.stderr @@ -21,6 +21,7 @@ LL | () found unit type `()` = help: consider constraining the associated type `::Assoc` to `()` or calling a method that returns `::Assoc` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Assoc` is defined as `()` in the implementation, but the generic bound `T` hides this definition error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:32:5 @@ -37,6 +38,7 @@ LL | generic::<()>() found associated type `<() as Foo>::Assoc` = help: consider constraining the associated type `<() as Foo>::Assoc` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the generic bound `()` hides this definition error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-projection.next.stderr b/tests/ui/specialization/specialization-default-projection.next.stderr index 9111f173a9c87..dac1069e189f8 100644 --- a/tests/ui/specialization/specialization-default-projection.next.stderr +++ b/tests/ui/specialization/specialization-default-projection.next.stderr @@ -21,6 +21,7 @@ LL | () found unit type `()` = help: consider constraining the associated type `::Assoc` to `()` or calling a method that returns `::Assoc` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Assoc` is defined as `()` in the implementation, but the generic bound `T` hides this definition error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:32:5 @@ -37,6 +38,7 @@ LL | generic::<()>() found associated type `<() as Foo>::Assoc` = help: consider constraining the associated type `<() as Foo>::Assoc` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the generic bound `()` hides this definition error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-types.current.stderr b/tests/ui/specialization/specialization-default-types.current.stderr index 09689681740ff..503e7ebbc433d 100644 --- a/tests/ui/specialization/specialization-default-types.current.stderr +++ b/tests/ui/specialization/specialization-default-types.current.stderr @@ -20,6 +20,7 @@ LL | Box::new(self) | = note: expected associated type `::Output` found struct `Box` + = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:29:5 @@ -33,6 +34,7 @@ LL | Example::generate(t) found associated type `::Output` = help: consider constraining the associated type `::Output` to `Box` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-types.next.stderr b/tests/ui/specialization/specialization-default-types.next.stderr index 1535c6473bddf..1774315eb8226 100644 --- a/tests/ui/specialization/specialization-default-types.next.stderr +++ b/tests/ui/specialization/specialization-default-types.next.stderr @@ -20,6 +20,7 @@ LL | Box::new(self) | = note: expected associated type `::Output` found struct `Box` + = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:29:5 @@ -33,6 +34,7 @@ LL | Example::generate(t) found associated type `::Output` = help: consider constraining the associated type `::Output` to `Box` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html + = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition error: aborting due to 2 previous errors; 1 warning emitted From c576dc55b8b485a31deb3c7f58bdc643027d7c9a Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Fri, 16 Jan 2026 11:41:15 +0530 Subject: [PATCH 03/10] delete middle check. Co-authored-by: lcnr --- .../rustc_trait_selection/src/error_reporting/infer/mod.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 86cec9f647b70..7a14901b32d9f 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -278,13 +278,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let is_shadowed = self.infcx.probe(|_| { let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs); - - let expected_trait_ref = alias.trait_ref(tcx); - - if !self.infcx.can_eq(param_env, expected_trait_ref, impl_trait_ref) { - return false; - } let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id) { From 071d0cd9f28d082e1cccd2c034b0e95d0b9c789b Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Tue, 10 Feb 2026 18:37:36 +0000 Subject: [PATCH 04/10] rewording note and refer issue --- .../rustc_trait_selection/src/error_reporting/infer/mod.rs | 3 ++- .../associated-types/param-env-shadowing-issue-149910.stderr | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 7a14901b32d9f..5597fe488c1a2 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -294,7 +294,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { if is_shadowed { diag.note(format!( "the associated type `{}` is defined as `{}` in the implementation, \ - but the generic bound `{}` hides this definition", + but the where-bound `{}` shadows this definition\n\ + see issue #152409 for more information", self.ty_to_string(tcx.mk_ty_from_kind(ty::Alias(ty::Projection, *alias))), self.ty_to_string(concrete), self.ty_to_string(alias.self_ty()) diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr index fb05f0add349d..b06770e526353 100644 --- a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr @@ -10,7 +10,8 @@ LL | x | = note: expected associated type `::Assoc` found type parameter `T` - = note: the associated type `::Assoc` is defined as `T` in the implementation, but the generic bound `T` hides this definition + = note: the associated type `::Assoc` is defined as `T` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information help: consider further restricting this bound | LL | fn foo>(x: T) -> T::Assoc { From 6b3c42592e0aa3dd748d40b5268b772b24b0e27a Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Tue, 10 Feb 2026 19:23:10 +0000 Subject: [PATCH 05/10] update tests --- ...training-assoc-type-because-of-assoc-const.stderr | 3 ++- .../associated-types/defaults-specialization.stderr | 12 ++++++++---- .../specialization-default-projection.current.stderr | 6 ++++-- .../specialization-default-projection.next.stderr | 6 ++++-- .../specialization-default-types.current.stderr | 6 ++++-- .../specialization-default-types.next.stderr | 6 ++++-- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr index af0db3a95993f..3b89ed66b355e 100644 --- a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr +++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr @@ -6,7 +6,8 @@ LL | const N: C::M = 4u8; | = note: expected associated type `::M` found type `u8` - = note: the associated type `::M` is defined as `u8` in the implementation, but the generic bound `C` hides this definition + = note: the associated type `::M` is defined as `u8` in the implementation, but the where-bound `C` shadows this definition + see issue #152409 for more information help: consider constraining the associated type `::M` to `u8` | LL | impl> U for u16 { diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr index be0e178e40315..d22d9ce659a76 100644 --- a/tests/ui/associated-types/defaults-specialization.stderr +++ b/tests/ui/associated-types/defaults-specialization.stderr @@ -75,7 +75,8 @@ LL | fn make() -> Self::Ty { 0u8 } found type `u8` = help: consider constraining the associated type ` as Tr>::Ty` to `u8` or calling a method that returns ` as Tr>::Ty` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - = note: the associated type ` as Tr>::Ty` is defined as `u8` in the implementation, but the generic bound `A2` hides this definition + = note: the associated type ` as Tr>::Ty` is defined as `u8` in the implementation, but the where-bound `A2` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:44:29 @@ -90,7 +91,8 @@ LL | fn make() -> Self::Ty { true } | = note: expected associated type ` as Tr>::Ty` found type `bool` - = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the generic bound `B2` hides this definition + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B2` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:87:32 @@ -123,7 +125,8 @@ help: a method is available that returns ` as Tr>::Ty` | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` - = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the generic bound `B<()>` hides this definition + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B<()>` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/defaults-specialization.rs:89:33 @@ -156,7 +159,8 @@ help: a method is available that returns ` as Tr>::Ty` | LL | fn make() -> Self::Ty { | ^^^^^^^^^^^^^^^^^^^^^ consider calling `Tr::make` - = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the generic bound `B2<()>` hides this definition + = note: the associated type ` as Tr>::Ty` is defined as `bool` in the implementation, but the where-bound `B2<()>` shadows this definition + see issue #152409 for more information error: aborting due to 9 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-projection.current.stderr b/tests/ui/specialization/specialization-default-projection.current.stderr index c50b053cf2dc1..b88c1a94baf91 100644 --- a/tests/ui/specialization/specialization-default-projection.current.stderr +++ b/tests/ui/specialization/specialization-default-projection.current.stderr @@ -21,7 +21,8 @@ LL | () found unit type `()` = help: consider constraining the associated type `::Assoc` to `()` or calling a method that returns `::Assoc` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - = note: the associated type `::Assoc` is defined as `()` in the implementation, but the generic bound `T` hides this definition + = note: the associated type `::Assoc` is defined as `()` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:32:5 @@ -38,7 +39,8 @@ LL | generic::<()>() found associated type `<() as Foo>::Assoc` = help: consider constraining the associated type `<() as Foo>::Assoc` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the generic bound `()` hides this definition + = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the where-bound `()` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-projection.next.stderr b/tests/ui/specialization/specialization-default-projection.next.stderr index dac1069e189f8..a385b16a2d8bd 100644 --- a/tests/ui/specialization/specialization-default-projection.next.stderr +++ b/tests/ui/specialization/specialization-default-projection.next.stderr @@ -21,7 +21,8 @@ LL | () found unit type `()` = help: consider constraining the associated type `::Assoc` to `()` or calling a method that returns `::Assoc` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - = note: the associated type `::Assoc` is defined as `()` in the implementation, but the generic bound `T` hides this definition + = note: the associated type `::Assoc` is defined as `()` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-projection.rs:32:5 @@ -38,7 +39,8 @@ LL | generic::<()>() found associated type `<() as Foo>::Assoc` = help: consider constraining the associated type `<() as Foo>::Assoc` to `()` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the generic bound `()` hides this definition + = note: the associated type `<() as Foo>::Assoc` is defined as `()` in the implementation, but the where-bound `()` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-types.current.stderr b/tests/ui/specialization/specialization-default-types.current.stderr index 503e7ebbc433d..8df170cbb767d 100644 --- a/tests/ui/specialization/specialization-default-types.current.stderr +++ b/tests/ui/specialization/specialization-default-types.current.stderr @@ -20,7 +20,8 @@ LL | Box::new(self) | = note: expected associated type `::Output` found struct `Box` - = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:29:5 @@ -34,7 +35,8 @@ LL | Example::generate(t) found associated type `::Output` = help: consider constraining the associated type `::Output` to `Box` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted diff --git a/tests/ui/specialization/specialization-default-types.next.stderr b/tests/ui/specialization/specialization-default-types.next.stderr index 1774315eb8226..4ea9b996c86a9 100644 --- a/tests/ui/specialization/specialization-default-types.next.stderr +++ b/tests/ui/specialization/specialization-default-types.next.stderr @@ -20,7 +20,8 @@ LL | Box::new(self) | = note: expected associated type `::Output` found struct `Box` - = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error[E0308]: mismatched types --> $DIR/specialization-default-types.rs:29:5 @@ -34,7 +35,8 @@ LL | Example::generate(t) found associated type `::Output` = help: consider constraining the associated type `::Output` to `Box` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html - = note: the associated type `::Output` is defined as `Box` in the implementation, but the generic bound `T` hides this definition + = note: the associated type `::Output` is defined as `Box` in the implementation, but the where-bound `T` shadows this definition + see issue #152409 for more information error: aborting due to 2 previous errors; 1 warning emitted From 1eddc1798998c9faed8725d249640ff7c63548ab Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Thu, 12 Feb 2026 12:10:08 +0000 Subject: [PATCH 06/10] fix GATs logic --- .../src/error_reporting/infer/mod.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 5597fe488c1a2..2475bc8f51e5e 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -58,6 +58,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::lang_items::LangItem; use rustc_hir::{self as hir}; +use rustc_infer::infer::DefineOpaqueTypes; use rustc_macros::extension; use rustc_middle::bug; use rustc_middle::dep_graph::DepContext; @@ -278,6 +279,21 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let is_shadowed = self.infcx.probe(|_| { let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); + let impl_trait_ref = + tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs); + + let expected_trait_ref = alias.trait_ref(tcx); + + if let Err(_) = self.infcx.at(&ObligationCause::dummy(), param_env).eq( + DefineOpaqueTypes::No, + expected_trait_ref, + impl_trait_ref, + ) { + return false; + } + + let trait_def_id = alias.trait_def_id(tcx); + let rebased_args = alias.args.rebase_onto(tcx, trait_def_id, impl_substs); let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id) { @@ -286,7 +302,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { }; let impl_item_def_id = leaf_def.item.def_id; - let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, impl_substs); + let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, rebased_args); self.infcx.can_eq(param_env, impl_assoc_ty, concrete) }); From 7a2f2fe754ada6d7d93e3a19bb171c3244ea2ee6 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Thu, 12 Feb 2026 12:20:36 +0000 Subject: [PATCH 07/10] fix tidy --- .../rustc_trait_selection/src/error_reporting/infer/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 2475bc8f51e5e..32bbc18f74696 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -279,8 +279,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { let is_shadowed = self.infcx.probe(|_| { let impl_substs = self.infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = - tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs); + let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).instantiate(tcx, impl_substs); let expected_trait_ref = alias.trait_ref(tcx); From 7a7d48ea626d12357546f8a4396a065703b58cc0 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Fri, 13 Feb 2026 05:32:55 +0000 Subject: [PATCH 08/10] add tests --- .../param-env-shadowing-false-positive.rs | 13 +++++++++++++ .../param-env-shadowing-false-positive.stderr | 18 ++++++++++++++++++ .../param-env-shadowing-gat.rs | 13 +++++++++++++ .../param-env-shadowing-gat.stderr | 18 ++++++++++++++++++ 4 files changed, 62 insertions(+) create mode 100644 tests/ui/associated-types/param-env-shadowing-false-positive.rs create mode 100644 tests/ui/associated-types/param-env-shadowing-false-positive.stderr create mode 100644 tests/ui/associated-types/param-env-shadowing-gat.rs create mode 100644 tests/ui/associated-types/param-env-shadowing-gat.stderr diff --git a/tests/ui/associated-types/param-env-shadowing-false-positive.rs b/tests/ui/associated-types/param-env-shadowing-false-positive.rs new file mode 100644 index 0000000000000..e40d36dabc813 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-false-positive.rs @@ -0,0 +1,13 @@ +trait Trait { + type Assoc; +} + +impl Trait for T { + type Assoc = T; +} + +fn foo(x: T::Assoc) -> u32 { + x //~ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/param-env-shadowing-false-positive.stderr b/tests/ui/associated-types/param-env-shadowing-false-positive.stderr new file mode 100644 index 0000000000000..f4a687196ca15 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-false-positive.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/param-env-shadowing-false-positive.rs:10:5 + | +LL | fn foo(x: T::Assoc) -> u32 { + | --- expected `u32` because of return type +LL | x + | ^ expected `u32`, found associated type + | + = note: expected type `u32` + found associated type `::Assoc` +help: consider constraining the associated type `::Assoc` to `u32` + | +LL | fn foo>(x: T::Assoc) -> u32 { + | +++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/associated-types/param-env-shadowing-gat.rs b/tests/ui/associated-types/param-env-shadowing-gat.rs new file mode 100644 index 0000000000000..c7c559eb83b22 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-gat.rs @@ -0,0 +1,13 @@ +trait Trait { + type Assoc; +} + +impl Trait for T { + type Assoc = U; +} + +fn foo(x: T::Assoc) -> u32 { + x //~ ERROR mismatched types +} + +fn main() {} diff --git a/tests/ui/associated-types/param-env-shadowing-gat.stderr b/tests/ui/associated-types/param-env-shadowing-gat.stderr new file mode 100644 index 0000000000000..ed6e92c64ae03 --- /dev/null +++ b/tests/ui/associated-types/param-env-shadowing-gat.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/param-env-shadowing-gat.rs:10:5 + | +LL | fn foo(x: T::Assoc) -> u32 { + | --- expected `u32` because of return type +LL | x + | ^ expected `u32`, found associated type + | + = note: expected type `u32` + found associated type `::Assoc` +help: consider constraining the associated type `::Assoc` to `u32` + | +LL | fn foo = u32>>(x: T::Assoc) -> u32 { + | ++++++++++++++++ + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 34981bf3cd9072adfe303cb2ea54d54d86ffb208 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Fri, 13 Feb 2026 14:44:40 +0000 Subject: [PATCH 09/10] add comments to tests --- .../ui/associated-types/param-env-shadowing-false-positive.rs | 4 ++++ .../param-env-shadowing-false-positive.stderr | 2 +- tests/ui/associated-types/param-env-shadowing-gat.rs | 4 ++++ tests/ui/associated-types/param-env-shadowing-gat.stderr | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/ui/associated-types/param-env-shadowing-false-positive.rs b/tests/ui/associated-types/param-env-shadowing-false-positive.rs index e40d36dabc813..41993f5cba19c 100644 --- a/tests/ui/associated-types/param-env-shadowing-false-positive.rs +++ b/tests/ui/associated-types/param-env-shadowing-false-positive.rs @@ -1,3 +1,7 @@ +// Regression test for issue #149910. +// The compiler previously incorrectly claimed that the local param-env bound +// shadowed the global impl, but they are actually the same. + trait Trait { type Assoc; } diff --git a/tests/ui/associated-types/param-env-shadowing-false-positive.stderr b/tests/ui/associated-types/param-env-shadowing-false-positive.stderr index f4a687196ca15..64d7950f41efc 100644 --- a/tests/ui/associated-types/param-env-shadowing-false-positive.stderr +++ b/tests/ui/associated-types/param-env-shadowing-false-positive.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/param-env-shadowing-false-positive.rs:10:5 + --> $DIR/param-env-shadowing-false-positive.rs:14:5 | LL | fn foo(x: T::Assoc) -> u32 { | --- expected `u32` because of return type diff --git a/tests/ui/associated-types/param-env-shadowing-gat.rs b/tests/ui/associated-types/param-env-shadowing-gat.rs index c7c559eb83b22..9dc91a1a14650 100644 --- a/tests/ui/associated-types/param-env-shadowing-gat.rs +++ b/tests/ui/associated-types/param-env-shadowing-gat.rs @@ -1,3 +1,7 @@ +// Regression test for issue #149910. +// This ensures that the diagnostics logic handles Generic Associated Types (GATs) +// correctly without crashing (ICE). + trait Trait { type Assoc; } diff --git a/tests/ui/associated-types/param-env-shadowing-gat.stderr b/tests/ui/associated-types/param-env-shadowing-gat.stderr index ed6e92c64ae03..02c024341724a 100644 --- a/tests/ui/associated-types/param-env-shadowing-gat.stderr +++ b/tests/ui/associated-types/param-env-shadowing-gat.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/param-env-shadowing-gat.rs:10:5 + --> $DIR/param-env-shadowing-gat.rs:14:5 | LL | fn foo(x: T::Assoc) -> u32 { | --- expected `u32` because of return type From 1be41648d4a3fd8e3116f8bcf1d25f23119a27c7 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Sat, 14 Feb 2026 21:32:57 +0000 Subject: [PATCH 10/10] move and add comment --- .../rustc_trait_selection/src/error_reporting/infer/mod.rs | 6 +++--- .../ui/associated-types/param-env-shadowing-issue-149910.rs | 3 +++ .../param-env-shadowing-issue-149910.stderr | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs index 32bbc18f74696..2b2f9a07890fb 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs @@ -291,15 +291,15 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { return false; } - let trait_def_id = alias.trait_def_id(tcx); - let rebased_args = alias.args.rebase_onto(tcx, trait_def_id, impl_substs); - let leaf_def = match specialization_graph::assoc_def(tcx, impl_def_id, alias.def_id) { Ok(leaf) => leaf, Err(_) => return false, }; + let trait_def_id = alias.trait_def_id(tcx); + let rebased_args = alias.args.rebase_onto(tcx, trait_def_id, impl_substs); + let impl_item_def_id = leaf_def.item.def_id; let impl_assoc_ty = tcx.type_of(impl_item_def_id).instantiate(tcx, rebased_args); diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.rs b/tests/ui/associated-types/param-env-shadowing-issue-149910.rs index bd4df859dc074..368b80e661895 100644 --- a/tests/ui/associated-types/param-env-shadowing-issue-149910.rs +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.rs @@ -1,3 +1,6 @@ +// Regression test for issue #149910. +// We want to tell the user about param_env shadowing here. + trait Trait { type Assoc; } diff --git a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr index b06770e526353..71ce456bfc1a8 100644 --- a/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr +++ b/tests/ui/associated-types/param-env-shadowing-issue-149910.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/param-env-shadowing-issue-149910.rs:10:5 + --> $DIR/param-env-shadowing-issue-149910.rs:13:5 | LL | fn foo(x: T) -> T::Assoc { | - -------- expected `::Assoc` because of return type