• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // check-pass
2 
3 // This test checks that we're correctly dealing with inductive cycles
4 // with canonical inference variables.
5 
6 trait Trait<T, U> {}
7 
8 trait IsNotU32 {}
9 impl IsNotU32 for i32 {}
10 impl<T: IsNotU32, U> Trait<T, U> for () // impl 1
11 where
12     (): Trait<U, T>
13 {}
14 
15 impl<T> Trait<u32, T> for () {} // impl 2
16 
17 // If we now check whether `(): Trait<?0, ?1>` holds this has to
18 // result in ambiguity as both `for<T> (): Trait<u32, T>` and `(): Trait<i32, u32>`
19 // applies. The remainder of this test asserts that.
20 
21 // If we were to error on inductive cycles with canonical inference variables
22 // this would be wrong:
23 
24 // (): Trait<?0, ?1>
25 //  - impl 1
26 //      - ?0: IsNotU32 // ambig
27 //      - (): Trait<?1, ?0> // canonical cycle -> err
28 //      - ERR
29 //  - impl 2
30 //      - OK ?0 == u32
31 //
32 // Result: OK ?0 == u32.
33 
34 // (): Trait<i32, u32>
35 //  - impl 1
36 //      - i32: IsNotU32 // ok
37 //      - (): Trait<u32, i32>
38 //          - impl 1
39 //              - u32: IsNotU32 // err
40 //              - ERR
41 //          - impl 2
42 //              - OK
43 //      - OK
44 //  - impl 2 (trivial ERR)
45 //
46 // Result OK
47 
48 // This would mean that `(): Trait<?0, ?1>` is not complete,
49 // which is unsound if we're in coherence.
50 
implements_trait<T, U>() -> (T, U) where (): Trait<T, U>,51 fn implements_trait<T, U>() -> (T, U)
52 where
53     (): Trait<T, U>,
54 {
55     todo!()
56 }
57 
58 // A hack to only constrain the infer vars after first checking
59 // the `(): Trait<_, _>`.
60 trait Constrain<T> {}
61 impl<T> Constrain<T> for  T {}
constrain<T: Constrain<U>, U>(_: U)62 fn constrain<T: Constrain<U>, U>(_: U) {}
63 
main()64 fn main() {
65     let (x, y) = implements_trait::<_, _>();
66 
67     constrain::<i32, _>(x);
68     constrain::<u32, _>(y);
69 }
70