diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs index f059a6fb785..513fc9355c8 100644 --- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs +++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs @@ -1212,8 +1212,28 @@ where // (including global ones) over everything else. let has_non_global_where_bounds = candidates.iter().any(|c| match c.source { CandidateSource::ParamEnv(idx) => { - let where_bound = goal.param_env.caller_bounds().get(idx); - where_bound.has_bound_vars() || !where_bound.is_global() + let where_bound = goal.param_env.caller_bounds().get(idx).unwrap(); + let ty::ClauseKind::Trait(trait_pred) = where_bound.kind().skip_binder() else { + unreachable!("expected trait-bound: {where_bound:?}"); + }; + + if trait_pred.has_bound_vars() || !trait_pred.is_global() { + return true; + } + + // We don't consider a trait-bound global if it has a projection bound. + // + // See ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs + // for an example where this is necessary. + for p in goal.param_env.caller_bounds().iter() { + if let ty::ClauseKind::Projection(proj) = p.kind().skip_binder() { + if proj.projection_term.trait_ref(self.cx()) == trait_pred.trait_ref { + return true; + } + } + } + + false } _ => false, }); diff --git a/tests/ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs b/tests/ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs new file mode 100644 index 00000000000..dc96652f82f --- /dev/null +++ b/tests/ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs @@ -0,0 +1,21 @@ +//@ compile-flags: -Znext-solver +//@ check-pass + +// `(): Trait` is a global where-bound with a projection bound. +// This previously resulted in ambiguity as we considered both +// the impl and the where-bound while normalizing. + +trait Trait { + type Assoc; +} +impl Trait for () { + type Assoc = &'static (); +} + +fn foo<'a>(x: <() as Trait>::Assoc) +where + (): Trait, +{ +} + +fn main() {}