// Like `projection-bound-cycle.rs` but this avoids using // `feature(trivial_bounds)`. #![feature(generic_associated_types)] trait Print { fn print(); } trait Foo { type Item: Sized where ::Item: Sized; } struct Number { t: T } impl Foo for Number { // Well-formedness checks require that the following // goal is true: // ``` // if ([T]: Sized) { # if the where clauses hold // [T]: Sized # then the bound on the associated type hold // } // ``` // which it is :) type Item = [T] where [T]: Sized; } struct OnlySized where T: Sized { f: T } impl Print for OnlySized { fn print() { println!("{}", std::mem::size_of::()); } } trait Bar { type Assoc: Print; } impl Bar for T where T: Foo { // This is not ok, we need to prove `wf(::Item)`, which requires // knowing that `::Item: Sized` to satisfy the where clause. We // can use the bound on `Foo::Item` for this, but that requires // `wf(::Item)`, which is an invalid cycle. type Assoc = OnlySized<::Item>; //~^ ERROR overflow evaluating the requirement `::Item: Sized` } fn foo() { T::print() // oops, in fact `T = OnlySized` which is ill-formed } fn bar() { // we have `FromEnv(T: Bar)` hence // `::Assoc` is well-formed and // `Implemented(::Assoc: Print)` hold foo::<::Assoc>() } fn main() { bar::>() }