1 pub trait DeclaredTrait {
2     type Type;
3 }
4 
5 impl DeclaredTrait for i32 {
6     type Type = i32;
7 }
8 
9 pub trait WhereTrait {
10     type Type;
11 }
12 
13 impl WhereTrait for i32 {
14     type Type = i32;
15 }
16 
17 // Make sure we don't add a bound that just shares a name with an associated
18 // type.
19 pub mod module {
20     pub type Type = i32;
21 }
22 
23 #[derive(PartialEq, Debug)]
24 struct PrivateStruct<T>(T);
25 
26 #[derive(PartialEq, Debug)]
27 struct TupleStruct<A, B: DeclaredTrait, C>(
28     module::Type,
29     Option<module::Type>,
30     A,
31     PrivateStruct<A>,
32     B,
33     B::Type,
34     Option<B::Type>,
35     <B as DeclaredTrait>::Type,
36     Option<<B as DeclaredTrait>::Type>,
37     C,
38     C::Type,
39     Option<C::Type>,
40     <C as WhereTrait>::Type,
41     Option<<C as WhereTrait>::Type>,
42     <i32 as DeclaredTrait>::Type,
43 ) where C: WhereTrait;
44 
45 #[derive(PartialEq, Debug)]
46 pub struct Struct<A, B: DeclaredTrait, C> where C: WhereTrait {
47     m1: module::Type,
48     m2: Option<module::Type>,
49     a1: A,
50     a2: PrivateStruct<A>,
51     b: B,
52     b1: B::Type,
53     b2: Option<B::Type>,
54     b3: <B as DeclaredTrait>::Type,
55     b4: Option<<B as DeclaredTrait>::Type>,
56     c: C,
57     c1: C::Type,
58     c2: Option<C::Type>,
59     c3: <C as WhereTrait>::Type,
60     c4: Option<<C as WhereTrait>::Type>,
61     d: <i32 as DeclaredTrait>::Type,
62 }
63 
64 #[derive(PartialEq, Debug)]
65 enum Enum<A, B: DeclaredTrait, C> where C: WhereTrait {
66     Unit,
67     Seq(
68         module::Type,
69         Option<module::Type>,
70         A,
71         PrivateStruct<A>,
72         B,
73         B::Type,
74         Option<B::Type>,
75         <B as DeclaredTrait>::Type,
76         Option<<B as DeclaredTrait>::Type>,
77         C,
78         C::Type,
79         Option<C::Type>,
80         <C as WhereTrait>::Type,
81         Option<<C as WhereTrait>::Type>,
82         <i32 as DeclaredTrait>::Type,
83     ),
84     Map {
85         m1: module::Type,
86         m2: Option<module::Type>,
87         a1: A,
88         a2: PrivateStruct<A>,
89         b: B,
90         b1: B::Type,
91         b2: Option<B::Type>,
92         b3: <B as DeclaredTrait>::Type,
93         b4: Option<<B as DeclaredTrait>::Type>,
94         c: C,
95         c1: C::Type,
96         c2: Option<C::Type>,
97         c3: <C as WhereTrait>::Type,
98         c4: Option<<C as WhereTrait>::Type>,
99         d: <i32 as DeclaredTrait>::Type,
100     },
101 }
102 
103 fn main() {
104 
105     let e: Enum<
106         i32,
107         i32,
108         i32,
109     > = Enum::Seq(
110         0,
111         None,
112         0,
113         PrivateStruct(0),
114         0,
115         0,
116         None,
117         0,
118         None,
119         0,
120         0,
121         None,
122         0,
123         None,
124         0,
125     );
126     assert_eq!(e, e);
127 
128     let e: Enum<
129         i32,
130         i32,
131         i32,
132     > = Enum::Map {
133         m1: 0,
134         m2: None,
135         a1: 0,
136         a2: PrivateStruct(0),
137         b: 0,
138         b1: 0,
139         b2: None,
140         b3: 0,
141         b4: None,
142         c: 0,
143         c1: 0,
144         c2: None,
145         c3: 0,
146         c4: None,
147         d: 0,
148     };
149     assert_eq!(e, e);
150         let e: TupleStruct<
151             i32,
152             i32,
153             i32,
154         > = TupleStruct(
155             0,
156             None,
157             0,
158             PrivateStruct(0),
159             0,
160             0,
161             None,
162             0,
163             None,
164             0,
165             0,
166             None,
167             0,
168             None,
169             0,
170         );
171         assert_eq!(e, e);
172 
173         let e: Struct<
174             i32,
175             i32,
176             i32,
177         > = Struct {
178             m1: 0,
179             m2: None,
180             a1: 0,
181             a2: PrivateStruct(0),
182             b: 0,
183             b1: 0,
184             b2: None,
185             b3: 0,
186             b4: None,
187             c: 0,
188             c1: 0,
189             c2: None,
190             c3: 0,
191             c4: None,
192             d: 0,
193         };
194         assert_eq!(e, e);
195 
196         let e = Enum::Unit::<i32, i32, i32>;
197         assert_eq!(e, e);
198 }
199