]> git.proxmox.com Git - rustc.git/blob - src/test/ui/generic-associated-types/projection-bound-cycle.rs
New upstream version 1.65.0+dfsg1
[rustc.git] / src / test / ui / generic-associated-types / projection-bound-cycle.rs
1 // Test case from Chalk.
2 // Make sure that we make sure that we don't allow arbitrary bounds to be
3 // proven when a bound and a where clause of an associated type are the same.
4
5 #![feature(trivial_bounds)]
6
7 trait Print {
8 fn print();
9 }
10
11 trait Foo {
12 type Item: Sized where <Self as Foo>::Item: Sized;
13 }
14
15 struct Number { }
16
17 impl Foo for Number {
18 // Well-formedness checks require that the following
19 // goal is true:
20 // ```
21 // if (str: Sized) { # if the where clauses hold
22 // str: Sized # then the bound on the associated type hold
23 // }
24 // ```
25 // which it is :)
26 type Item = str where str: Sized;
27 }
28
29 struct OnlySized<T> where T: Sized { f: T }
30 impl<T> Print for OnlySized<T> {
31 fn print() {
32 println!("{}", std::mem::size_of::<T>());
33 }
34 }
35
36 trait Bar {
37 type Assoc: Print;
38 }
39
40 impl<T> Bar for T where T: Foo {
41 // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires
42 // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We
43 // can use the bound on `Foo::Item` for this, but that requires
44 // `wf(<T as Foo>::Item)`, which is an invalid cycle.
45 type Assoc = OnlySized<<T as Foo>::Item>;
46 //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
47 }
48
49 fn foo<T: Print>() {
50 T::print() // oops, in fact `T = OnlySized<str>` which is ill-formed
51 }
52
53 fn bar<T: Bar>() {
54 // we have `FromEnv(T: Bar)` hence
55 // `<T as Bar>::Assoc` is well-formed and
56 // `Implemented(<T as Bar>::Assoc: Print)` hold
57 foo::<<T as Bar>::Assoc>()
58 }
59
60 fn main() {
61 bar::<Number>()
62 }