]> git.lizzy.rs Git - rust.git/blob - src/test/ui/generic-associated-types/projection-bound-cycle-generic.rs
Rollup merge of #102954 - GuillaumeGomez:cfg-hide-attr-checks, r=Manishearth
[rust.git] / src / test / 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 }
25
26 struct OnlySized<T> where T: Sized { f: T }
27 impl<T> Print for OnlySized<T> {
28     fn print() {
29         println!("{}", std::mem::size_of::<T>());
30     }
31 }
32
33 trait Bar {
34     type Assoc: Print;
35 }
36
37 impl<T> Bar for T where T: Foo {
38     // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires
39     // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We
40     // can use the bound on `Foo::Item` for this, but that requires
41     // `wf(<T as Foo>::Item)`, which is an invalid cycle.
42     type Assoc = OnlySized<<T as Foo>::Item>;
43     //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized`
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 }