handle global trait bounds defining assoc type
This commit is contained in:
parent
7171fee4ec
commit
09b784fac5
2 changed files with 43 additions and 2 deletions
|
@ -1212,8 +1212,28 @@ where
|
||||||
// (including global ones) over everything else.
|
// (including global ones) over everything else.
|
||||||
let has_non_global_where_bounds = candidates.iter().any(|c| match c.source {
|
let has_non_global_where_bounds = candidates.iter().any(|c| match c.source {
|
||||||
CandidateSource::ParamEnv(idx) => {
|
CandidateSource::ParamEnv(idx) => {
|
||||||
let where_bound = goal.param_env.caller_bounds().get(idx);
|
let where_bound = goal.param_env.caller_bounds().get(idx).unwrap();
|
||||||
where_bound.has_bound_vars() || !where_bound.is_global()
|
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,
|
_ => false,
|
||||||
});
|
});
|
||||||
|
|
|
@ -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<Assoc = &'a ()>,
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue