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(generic_associated_types)] 6 #![feature(trivial_bounds)] 7 8 trait Print { print()9 fn print(); 10 } 11 12 trait Foo { 13 type Item: Sized where <Self as Foo>::Item: Sized; 14 } 15 16 struct Number { } 17 18 impl Foo for Number { 19 // Well-formedness checks require that the following 20 // goal is true: 21 // ``` 22 // if (str: Sized) { # if the where clauses hold 23 // str: Sized # then the bound on the associated type hold 24 // } 25 // ``` 26 // which it is :) 27 type Item where str: Sized = str; 28 } 29 30 struct OnlySized<T> where T: Sized { f: T } 31 impl<T> Print for OnlySized<T> { print()32 fn print() { 33 println!("{}", std::mem::size_of::<T>()); 34 } 35 } 36 37 trait Bar { 38 type Assoc: Print; 39 } 40 41 impl<T> Bar for T where T: Foo { 42 // This is not ok, we need to prove `wf(<T as Foo>::Item)`, which requires 43 // knowing that `<T as Foo>::Item: Sized` to satisfy the where clause. We 44 // can use the bound on `Foo::Item` for this, but that requires 45 // `wf(<T as Foo>::Item)`, which is an invalid cycle. 46 type Assoc = OnlySized<<T as Foo>::Item>; 47 //~^ ERROR overflow evaluating the requirement `<T as Foo>::Item: Sized` 48 } 49 foo<T: Print>()50fn foo<T: Print>() { 51 T::print() // oops, in fact `T = OnlySized<str>` which is ill-formed 52 } 53 bar<T: Bar>()54fn bar<T: Bar>() { 55 // we have `FromEnv(T: Bar)` hence 56 // `<T as Bar>::Assoc` is well-formed and 57 // `Implemented(<T as Bar>::Assoc: Print)` hold 58 foo::<<T as Bar>::Assoc>() 59 } 60 main()61fn main() { 62 bar::<Number>() 63 } 64