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