]> git.lizzy.rs Git - rust.git/blob - tests/ui/generic-associated-types/projection-bound-cycle-generic.rs
Auto merge of #106696 - kylematsuda:early-binder, r=lcnr
[rust.git] / tests / ui / generic-associated-types / projection-bound-cycle-generic.rs
1 // Like `projection-bound-cycle.rs` but this avoids using
2 // `feature(trivial_bounds)`.
3
4 trait Print {
5     fn print();
6 }
7
8 trait Foo {
9     type Item: Sized where <Self as Foo>::Item: Sized;
10 }
11
12 struct Number<T> { t: T }
13
14 impl<T> Foo for Number<T> {
15     // Well-formedness checks require that the following
16     // goal is true:
17     // ```
18     // if ([T]: Sized) { # if the where clauses hold
19     //     [T]: Sized # then the bound on the associated type hold
20     // }
21     // ```
22     // which it is :)
23     type Item = [T] where [T]: Sized;
24     //~^ ERROR overflow evaluating the requirement `<Number<T> as Foo>::Item == _`
25 }
26
27 struct OnlySized<T> where T: Sized { f: T }
28 impl<T> Print for OnlySized<T> {
29     fn print() {
30         println!("{}", std::mem::size_of::<T>());
31     }
32 }
33
34 trait Bar {
35     type Assoc: Print;
36 }
37
38 impl<T> Bar for T where T: Foo {
39     // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires
40     // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We
41     // can use the bound on `Foo::Item` for this, but that requires
42     // `wf(<T as Foo>::Item)`, which is an invalid cycle.
43     type Assoc = OnlySized<<T as Foo>::Item>;
44 }
45
46 fn foo<T: Print>() {
47     T::print() // oops, in fact `T = OnlySized<str>` which is ill-formed
48 }
49
50 fn bar<T: Bar>() {
51     // we have `FromEnv(T: Bar)` hence
52     // `<T as Bar>::Assoc` is well-formed and
53     // `Implemented(<T as Bar>::Assoc: Print)` hold
54     foo::<<T as Bar>::Assoc>()
55 }
56
57 fn main() {
58     bar::<Number<u8>>()
59 }