Skip to content

Commit d52c615

Browse files
committed
handle global trait bounds defining assoc type
1 parent 4fb52b6 commit d52c615

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,8 +1211,28 @@ where
12111211
// (including global ones) over everything else.
12121212
let has_non_global_where_bounds = candidates.iter().any(|c| match c.source {
12131213
CandidateSource::ParamEnv(idx) => {
1214-
let where_bound = goal.param_env.caller_bounds().get(idx);
1215-
where_bound.has_bound_vars() || !where_bound.is_global()
1214+
let where_bound = goal.param_env.caller_bounds().get(idx).unwrap();
1215+
let ty::ClauseKind::Trait(trait_pred) = where_bound.kind().skip_binder() else {
1216+
unreachable!("expected trait-bound: {where_bound:?}");
1217+
};
1218+
1219+
if trait_pred.has_bound_vars() || !trait_pred.is_global() {
1220+
return true;
1221+
}
1222+
1223+
// We don't consider a trait-bound global if it has a projection bound.
1224+
//
1225+
// See ui/traits/next-solver/normalization-shadowing/global-trait-with-project.rs
1226+
// for an example where this is necessary.
1227+
for p in goal.param_env.caller_bounds().iter() {
1228+
if let ty::ClauseKind::Projection(proj) = p.kind().skip_binder() {
1229+
if proj.projection_term.trait_ref(self.cx()) == trait_pred.trait_ref {
1230+
return true;
1231+
}
1232+
}
1233+
}
1234+
1235+
false
12161236
}
12171237
_ => false,
12181238
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ compile-flags: -Znext-solver
2+
//@ check-pass
3+
4+
// `(): Trait` is a global where-bound with a projection bound.
5+
// This previously resulted in ambiguity as we considered both
6+
// the impl and the where-bound while normalizing.
7+
8+
trait Trait {
9+
type Assoc;
10+
}
11+
impl Trait for () {
12+
type Assoc = &'static ();
13+
}
14+
15+
fn foo<'a>(x: <() as Trait>::Assoc)
16+
where
17+
(): Trait<Assoc = &'a ()>,
18+
{
19+
}
20+
21+
fn main() {}

0 commit comments

Comments
 (0)