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