Skip to content

Commit fa551a1

Browse files
Collect relevant item bounds from trait clauses for nested rigid projections
1 parent 0af2783 commit fa551a1

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

compiler/rustc_hir_analysis/src/collect/item_bounds.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,22 @@ fn associated_type_bounds<'tcx>(
3535
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
3636

3737
let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {
38-
match pred.kind().skip_binder() {
39-
ty::ClauseKind::Trait(tr) => tr.self_ty() == item_ty,
40-
ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty() == item_ty,
41-
ty::ClauseKind::TypeOutlives(outlives) => outlives.0 == item_ty,
42-
_ => false,
38+
let mut clause_ty = match pred.kind().skip_binder() {
39+
ty::ClauseKind::Trait(tr) => tr.self_ty(),
40+
ty::ClauseKind::Projection(proj) => proj.projection_ty.self_ty(),
41+
ty::ClauseKind::TypeOutlives(outlives) => outlives.0,
42+
_ => return false,
43+
};
44+
45+
loop {
46+
if clause_ty == item_ty {
47+
return true;
48+
} else if let ty::Alias(ty::Projection, alias_ty) = *clause_ty.kind() {
49+
clause_ty = alias_ty.self_ty();
50+
continue;
51+
}
52+
53+
return false;
4354
}
4455
});
4556

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// check-pass
2+
// revisions: current next
3+
//[next] compile-flags: -Znext-solver
4+
5+
trait Trait
6+
where
7+
Self::Assoc: Clone,
8+
{
9+
type Assoc;
10+
}
11+
12+
fn foo<T: Trait>(x: &T::Assoc) -> T::Assoc {
13+
x.clone()
14+
}
15+
16+
trait Trait2
17+
where
18+
Self::Assoc: Iterator,
19+
<Self::Assoc as Iterator>::Item: Clone,
20+
{
21+
type Assoc;
22+
}
23+
24+
fn foo2<T: Trait2>(x: &<T::Assoc as Iterator>::Item) -> <T::Assoc as Iterator>::Item {
25+
x.clone()
26+
}
27+
28+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// check-pass
2+
// revisions: current next
3+
//[next] compile-flags: -Znext-solver
4+
5+
trait Foo
6+
where
7+
Self::Iterator: Iterator,
8+
<Self::Iterator as Iterator>::Item: Bar,
9+
{
10+
type Iterator;
11+
12+
fn iter() -> Self::Iterator;
13+
}
14+
15+
trait Bar {
16+
fn bar(&self);
17+
}
18+
19+
fn x<T: Foo>() {
20+
T::iter().next().unwrap().bar();
21+
}
22+
23+
fn main() {}

0 commit comments

Comments
 (0)