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] 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 cfe5b1f42556..86cec9f647b7 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 08f1d947dfb5..1fde7e5d43b7 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 21bc37bb3ea2..af0db3a95993 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 7d19ac85982a..be0e178e4031 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 57eaaee9906b..fb05f0add349 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 038c379c43e1..c50b053cf2dc 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 9111f173a9c8..dac1069e189f 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 09689681740f..503e7ebbc433 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 1535c6473bdd..1774315eb822 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