1 trait Foo<A> {
get(&self, A: &A)2 fn get(&self, A: &A) { }
3 }
4
5 trait Bar {
6 type Out;
7 }
8
9 impl<T> Foo<T> for [isize;0] {
10 // OK, T is used in `Foo<T>`.
11 }
12
13 impl<T,U> Foo<T> for [isize;1] {
14 //~^ ERROR the type parameter `U` is not constrained
15 }
16
17 impl<T,U> Foo<T> for [isize;2] where T : Bar<Out=U> {
18 // OK, `U` is now constrained by the output type parameter.
19 }
20
21 impl<T:Bar<Out=U>,U> Foo<T> for [isize;3] {
22 // OK, same as above but written differently.
23 }
24
25 impl<T,U> Foo<T> for U {
26 // OK, T, U are used everywhere. Note that the coherence check
27 // hasn't executed yet, so no errors about overlap.
28 }
29
30 impl<T,U> Bar for T {
31 //~^ ERROR the type parameter `U` is not constrained
32
33 type Out = U;
34
35 // Using `U` in an associated type within the impl is not good enough!
36 }
37
38 impl<T,U> Bar for T
39 where T : Bar<Out=U>
40 {
41 //~^^^ ERROR the type parameter `U` is not constrained
42
43 // This crafty self-referential attempt is still no good.
44 }
45
46 impl<T,U,V> Foo<T> for T
47 where (T,U): Bar<Out=V>
48 {
49 //~^^^ ERROR the type parameter `U` is not constrained
50 //~| ERROR the type parameter `V` is not constrained
51
52 // Here, `V` is bound by an output type parameter, but the inputs
53 // are not themselves constrained.
54 }
55
56 impl<T,U,V> Foo<(T,U)> for T
57 where (T,U): Bar<Out=V>
58 {
59 // As above, but both T and U ARE constrained.
60 }
61
main()62 fn main() { }
63