1 // Minimized case from typenum that didn't compile because:
2 // - We tried to normalize the ParamEnv of the second impl
3 // - This requires trying to normalize `GrEq<Self, Square<Square<U>>>`
4 // - This requires proving `Square<Square<U>>: Sized` so that the first impl
5 //   applies
6 // - This requires Providing `Square<Square<U>>` is well-formed, so that we
7 //   can use the `Sized` bound on `Mul::Output`
8 // - This requires proving `Square<U>: Mul`
9 // - But first we tried normalizing the whole obligation, including the
10 //   ParamEnv, which leads to a cycle error.
11 
12 // check-pass
13 
14 trait PrivateSquareRoot {}
15 
16 pub trait Mul<Rhs = Self> {
17     type Output;
18 }
19 
20 pub trait IsGreaterOrEqual<Rhs> {
21     type Output;
22 }
23 
24 pub type Square<A> = <A as Mul>::Output;
25 pub type GrEq<A, B> = <A as IsGreaterOrEqual<B>>::Output;
26 
27 impl<A, B> IsGreaterOrEqual<B> for A {
28     type Output = ();
29 }
30 
31 impl<U> PrivateSquareRoot for U
32 where
33     U: Mul,
34     Square<U>: Mul,
35     GrEq<Self, Square<Square<U>>>: Sized,
36 {
37 }
38 
main()39 fn main() {}
40