@@ -130,7 +130,7 @@ mod method_non_parametric_impl {
130
130
println ! ( "{:?}" , y. a) ; // $ fieldof=MyThing
131
131
132
132
println ! ( "{:?}" , x. m1( ) ) ; // $ MISSING: method=MyThing<S1>::m1
133
- println ! ( "{:?}" , y. m1( ) . a) ; // $ MISSING: method=MyThing<S2>::m1, field =MyThing
133
+ println ! ( "{:?}" , y. m1( ) . a) ; // $ MISSING: method=MyThing<S2>::m1 fieldof =MyThing
134
134
135
135
let x = MyThing { a : S1 } ;
136
136
let y = MyThing { a : S2 } ;
@@ -141,15 +141,23 @@ mod method_non_parametric_impl {
141
141
}
142
142
143
143
mod method_non_parametric_trait_impl {
144
- #[ derive( Debug ) ]
144
+ #[ derive( Debug , Clone , Copy ) ]
145
145
struct MyThing < A > {
146
146
a : A ,
147
147
}
148
148
149
- #[ derive( Debug ) ]
149
+ #[ derive( Debug , Clone , Copy ) ]
150
+ struct MyPair < P1 , P2 > {
151
+ p1 : P1 ,
152
+ p2 : P2 ,
153
+ }
154
+
155
+ #[ derive( Debug , Clone , Copy ) ]
150
156
struct S1 ;
151
- #[ derive( Debug ) ]
157
+ #[ derive( Debug , Clone , Copy ) ]
152
158
struct S2 ;
159
+ #[ derive( Debug , Clone , Copy , Default ) ]
160
+ struct S3 ;
153
161
154
162
trait MyTrait < A > {
155
163
fn m1 ( self ) -> A ;
@@ -162,6 +170,13 @@ mod method_non_parametric_trait_impl {
162
170
}
163
171
}
164
172
173
+ trait MyProduct < A , B > {
174
+ // MyProduct::fst
175
+ fn fst ( self ) -> A ;
176
+ // MyProduct::snd
177
+ fn snd ( self ) -> B ;
178
+ }
179
+
165
180
fn call_trait_m1 < T1 , T2 : MyTrait < T1 > > ( x : T2 ) -> T1 {
166
181
x. m1 ( ) // $ method=m1
167
182
}
@@ -180,18 +195,170 @@ mod method_non_parametric_trait_impl {
180
195
}
181
196
}
182
197
198
+ // Implementation where the type parameter `TD` only occurs in the
199
+ // implemented trait and not the implementing type.
200
+ impl < TD > MyTrait < TD > for MyThing < S3 >
201
+ where
202
+ TD : Default ,
203
+ {
204
+ // MyThing<S3>::m1
205
+ fn m1 ( self ) -> TD {
206
+ TD :: default ( )
207
+ }
208
+ }
209
+
210
+ impl < I > MyTrait < I > for MyPair < I , S1 > {
211
+ // MyTrait<I>::m1
212
+ fn m1 ( self ) -> I {
213
+ self . p1 // $ fieldof=MyPair
214
+ }
215
+ }
216
+
217
+ impl MyTrait < S3 > for MyPair < S1 , S2 > {
218
+ // MyTrait<S3>::m1
219
+ fn m1 ( self ) -> S3 {
220
+ S3
221
+ }
222
+ }
223
+
224
+ impl < TT > MyTrait < TT > for MyPair < MyThing < TT > , S3 > {
225
+ // MyTrait<TT>::m1
226
+ fn m1 ( self ) -> TT {
227
+ let alpha = self . p1 ; // $ fieldof=MyPair
228
+ alpha. a // $ fieldof=MyThing
229
+ }
230
+ }
231
+
232
+ // This implementation only applies if the two type parameters are equal.
233
+ impl < A > MyProduct < A , A > for MyPair < A , A > {
234
+ // MyPair<A,A>::fst
235
+ fn fst ( self ) -> A {
236
+ self . p1 // $ fieldof=MyPair
237
+ }
238
+
239
+ // MyPair<A,A>::snd
240
+ fn snd ( self ) -> A {
241
+ self . p2 // $ fieldof=MyPair
242
+ }
243
+ }
244
+
245
+ // This implementation swaps the type parameters.
246
+ impl MyProduct < S1 , S2 > for MyPair < S2 , S1 > {
247
+ // MyPair<S2,S1>::fst
248
+ fn fst ( self ) -> S1 {
249
+ self . p2 // $ fieldof=MyPair
250
+ }
251
+
252
+ // MyPair<S2,S1>::snd
253
+ fn snd ( self ) -> S2 {
254
+ self . p1 // $ fieldof=MyPair
255
+ }
256
+ }
257
+
258
+ fn get_fst < V1 , V2 , P : MyProduct < V1 , V2 > > ( p : P ) -> V1 {
259
+ p. fst ( ) // $ method=MyProduct::fst
260
+ }
261
+
262
+ fn get_snd < V1 , V2 , P : MyProduct < V1 , V2 > > ( p : P ) -> V2 {
263
+ p. snd ( ) // $ method=MyProduct::snd
264
+ }
265
+
266
+ fn get_snd_fst < V0 , V1 , V2 , P : MyProduct < V1 , V2 > > ( p : MyPair < V0 , P > ) -> V1 {
267
+ p. p2 . fst ( ) // $ fieldof=MyPair method=MyProduct::fst
268
+ }
269
+
270
+ trait ConvertTo < T > {
271
+ // ConvertTo::convert_to
272
+ fn convert_to ( self ) -> T ;
273
+ }
274
+
275
+ impl < T : MyTrait < S1 > > ConvertTo < S1 > for T {
276
+ // T::convert_to
277
+ fn convert_to ( self ) -> S1 {
278
+ self . m1 ( ) // $ method=m1
279
+ }
280
+ }
281
+
282
+ fn convert_to < TS , T : ConvertTo < TS > > ( thing : T ) -> TS {
283
+ thing. convert_to ( ) // $ method=ConvertTo::convert_to
284
+ }
285
+
286
+ fn type_bound_type_parameter_impl < TP : MyTrait < S1 > > ( thing : TP ) -> S1 {
287
+ // The trait bound on `TP` makes the implementation of `ConvertTo` valid
288
+ thing. convert_to ( ) // $ MISSING: method=T::convert_to
289
+ }
290
+
183
291
pub fn f ( ) {
184
- let x = MyThing { a : S1 } ;
185
- let y = MyThing { a : S2 } ;
292
+ let thing_s1 = MyThing { a : S1 } ;
293
+ let thing_s2 = MyThing { a : S2 } ;
294
+ let thing_s3 = MyThing { a : S3 } ;
186
295
187
- println ! ( "{:?}" , x. m1( ) ) ; // $ MISSING: method=MyThing<S1>::m1
188
- println ! ( "{:?}" , y. m1( ) . a) ; // $ MISSING: method=MyThing<S2>::m1, field=MyThing
296
+ // Tests for method resolution
189
297
190
- let x = MyThing { a : S1 } ;
191
- let y = MyThing { a : S2 } ;
298
+ println ! ( "{:?}" , thing_s1. m1( ) ) ; // $ MISSING: method=MyThing<S1>::m1
299
+ println ! ( "{:?}" , thing_s2. m1( ) . a) ; // $ MISSING: method=MyThing<S2>::m1 fieldof=MyThing
300
+ let s3: S3 = thing_s3. m1 ( ) ; // $ MISSING: method=MyThing<S3>::m1
301
+ println ! ( "{:?}" , s3) ;
302
+
303
+ let p1 = MyPair { p1 : S1 , p2 : S1 } ;
304
+ println ! ( "{:?}" , p1. m1( ) ) ; // $ MISSING: method=MyTrait<I>::m1
192
305
193
- println ! ( "{:?}" , call_trait_m1( x) ) ; // MISSING: type=call_trait_m1(...):S1
194
- println ! ( "{:?}" , call_trait_m1( y) . a) ; // MISSING: field=MyThing
306
+ let p2 = MyPair { p1 : S1 , p2 : S2 } ;
307
+ println ! ( "{:?}" , p2. m1( ) ) ; // $ MISSING: method=MyTrait<S3>::m1
308
+
309
+ let p3 = MyPair {
310
+ p1 : MyThing { a : S1 } ,
311
+ p2 : S3 ,
312
+ } ;
313
+ println ! ( "{:?}" , p3. m1( ) ) ; // $ MISSING: method=MyTrait<TT>::m1
314
+
315
+ // These calls go to the first implementation of `MyProduct` for `MyPair`
316
+ let a = MyPair { p1 : S1 , p2 : S1 } ;
317
+ let x = a. fst ( ) ; // $ method=MyPair<A,A>::fst
318
+ println ! ( "{:?}" , x) ;
319
+ let y = a. snd ( ) ; // $ method=MyPair<A,A>::snd
320
+ println ! ( "{:?}" , y) ;
321
+
322
+ // These calls go to the last implementation of `MyProduct` for
323
+ // `MyPair`. The first implementation does not apply as the type
324
+ // parameters of the implementation enforce that the two generics must
325
+ // be equal.
326
+ let b = MyPair { p1 : S2 , p2 : S1 } ;
327
+ let x = b. fst ( ) ; // $ MISSING: method=MyPair<S2,S1>::fst SPURIOUS: method=MyPair<A,A>::fst
328
+ println ! ( "{:?}" , x) ;
329
+ let y = b. snd ( ) ; // $ MISSING: method=MyPair<S2,S1>::snd SPURIOUS: method=MyPair<A,A>::snd
330
+ println ! ( "{:?}" , y) ;
331
+
332
+ // Tests for inference of type parameters based on trait implementations.
333
+
334
+ let x = call_trait_m1 ( thing_s1) ; // $ MISSING: type=x:S1
335
+ println ! ( "{:?}" , x) ;
336
+ let y = call_trait_m1 ( thing_s2) ; // $ MISSING: type=y:MyThing type=y.A:S2
337
+ println ! ( "{:?}" , y. a) ; // $ MISSING: fieldof=MyThing
338
+
339
+ // First implementation
340
+ let a = MyPair { p1 : S1 , p2 : S1 } ;
341
+ let x = get_fst ( a) ; // $ type=x:S1
342
+ println ! ( "{:?}" , x) ;
343
+ let y = get_snd ( a) ; // $ type=y:S1
344
+ println ! ( "{:?}" , y) ;
345
+
346
+ // Second implementation
347
+ let b = MyPair { p1 : S2 , p2 : S1 } ;
348
+ let x = get_fst ( b) ; // $ type=x:S1 SPURIOUS: type=x:S2
349
+ println ! ( "{:?}" , x) ;
350
+ let y = get_snd ( b) ; // $ type=y:S2 SPURIOUS: type=y:S1
351
+ println ! ( "{:?}" , y) ;
352
+
353
+ let c = MyPair {
354
+ p1 : S3 ,
355
+ p2 : MyPair { p1 : S2 , p2 : S1 } ,
356
+ } ;
357
+ let x = get_snd_fst ( c) ; // $ type=x:S1 SPURIOUS: type=x:S2
358
+
359
+ let thing = MyThing { a : S1 } ;
360
+ let i = thing. convert_to ( ) ; // $ MISSING: type=i:S1 MISSING: method=T::convert_to
361
+ let j = convert_to ( thing) ; // $ MISSING: type=j:S1
195
362
}
196
363
}
197
364
@@ -219,13 +386,13 @@ mod type_parameter_bounds {
219
386
fn call_first_trait_per_bound < I : Debug , T : SecondTrait < I > > ( x : T ) {
220
387
// The type parameter bound determines which method this call is resolved to.
221
388
let s1 = x. method ( ) ; // $ method=SecondTrait::method
222
- println ! ( "{:?}" , s1) ;
389
+ println ! ( "{:?}" , s1) ; // $ type=s1:I
223
390
}
224
391
225
392
fn call_second_trait_per_bound < I : Debug , T : SecondTrait < I > > ( x : T ) {
226
393
// The type parameter bound determines which method this call is resolved to.
227
394
let s2 = x. method ( ) ; // $ method=SecondTrait::method
228
- println ! ( "{:?}" , s2) ;
395
+ println ! ( "{:?}" , s2) ; // $ type=s2:I
229
396
}
230
397
231
398
fn trait_bound_with_type < T : FirstTrait < S1 > > ( x : T ) {
@@ -235,7 +402,7 @@ mod type_parameter_bounds {
235
402
236
403
fn trait_per_bound_with_type < T : FirstTrait < S1 > > ( x : T ) {
237
404
let s = x. method ( ) ; // $ method=FirstTrait::method
238
- println ! ( "{:?}" , s) ;
405
+ println ! ( "{:?}" , s) ; // $ type=s:S1
239
406
}
240
407
241
408
trait Pair < P1 , P2 > {
@@ -323,8 +490,10 @@ mod function_trait_bounds {
323
490
a : MyThing { a : S2 } ,
324
491
} ;
325
492
326
- println ! ( "{:?}" , call_trait_thing_m1( x3) ) ;
327
- println ! ( "{:?}" , call_trait_thing_m1( y3) ) ;
493
+ let a = call_trait_thing_m1 ( x3) ; // $ type=a:S1
494
+ println ! ( "{:?}" , a) ;
495
+ let b = call_trait_thing_m1 ( y3) ; // $ type=b:S2
496
+ println ! ( "{:?}" , b) ;
328
497
}
329
498
}
330
499
@@ -584,14 +753,14 @@ mod method_supertraits {
584
753
let x = MyThing { a : S1 } ;
585
754
let y = MyThing { a : S2 } ;
586
755
587
- println ! ( "{:?}" , x. m2( ) ) ; // $ method=m2
588
- println ! ( "{:?}" , y. m2( ) ) ; // $ method=m2
756
+ println ! ( "{:?}" , x. m2( ) ) ; // $ method=m2 type=x.m2():S1
757
+ println ! ( "{:?}" , y. m2( ) ) ; // $ method=m2 type=y.m2():S2
589
758
590
759
let x = MyThing2 { a : S1 } ;
591
760
let y = MyThing2 { a : S2 } ;
592
761
593
- println ! ( "{:?}" , x. m3( ) ) ; // $ method=m3
594
- println ! ( "{:?}" , y. m3( ) ) ; // $ method=m3
762
+ println ! ( "{:?}" , x. m3( ) ) ; // $ method=m3 type=x.m3():S1
763
+ println ! ( "{:?}" , y. m3( ) ) ; // $ method=m3 type=y.m3():S2
595
764
}
596
765
}
597
766
@@ -767,7 +936,7 @@ mod option_methods {
767
936
println ! ( "{:?}" , x4) ;
768
937
769
938
let x5 = MyOption :: MySome ( MyOption :: < S > :: MyNone ( ) ) ;
770
- println ! ( "{:?}" , x5. flatten( ) ) ; // MISSING: method=flatten
939
+ println ! ( "{:?}" , x5. flatten( ) ) ; // $ MISSING: method=flatten
771
940
772
941
let x6 = MyOption :: MySome ( MyOption :: < S > :: MyNone ( ) ) ;
773
942
println ! ( "{:?}" , MyOption :: <MyOption <S >>:: flatten( x6) ) ;
0 commit comments