From 2fbb75198536302356e430fdff54f8a03463c4c2 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Thu, 30 Oct 2025 20:22:45 +0800 Subject: [PATCH] Un-shadow object bound candidate in `NormalizesTo` goal --- .../src/solve/assembly/mod.rs | 6 ++++++ .../use_object_if_empty_env.rs | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index c9a42dddac42..42eb804431e4 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -1143,6 +1143,12 @@ pub(super) fn assemble_and_merge_candidates>( // See `tests/ui/winnowing/norm-where-bound-gt-alias-bound.rs`. if candidates.iter().any(|c| matches!(c.source, CandidateSource::ParamEnv(_))) { candidates.retain(|c| matches!(c.source, CandidateSource::ParamEnv(_))); + } else if matches!(goal.predicate.self_ty().kind(), ty::Dynamic(..)) { + // Object candidate may be shadowed by where-bound for the trait goal, see + // `tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs`. + // Trait objects always have their associated types specified so `candidates` + // won't be empty. + self.assemble_object_bound_candidates(goal, &mut candidates); } else if candidates.is_empty() { // If the trait goal has been proven by using the environment, we want to treat // aliases as rigid if there are no applicable projection bounds in the environment. diff --git a/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs new file mode 100644 index 000000000000..ec3a94a97294 --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/use_object_if_empty_env.rs @@ -0,0 +1,17 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +trait Trait { + type Assoc; +} + +// We have param env candidate for the trait goal but not the projection. +// Under such circumstance, consider object candidate if the self_ty is trait object. +fn foo(x: as Trait>::Assoc) -> T +where + dyn Trait: Trait, +{ + x +} + +fn main() {}