@@ -236,21 +236,31 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
236
236
trait_ty_generics : & ty:: Generics ) {
237
237
// If declaration is
238
238
//
239
- // trait<'a,'b,'c,A,B,C > {
240
- // fn foo<'d,'e,'f,D,E,F >(...) -> Self;
239
+ // trait Trait <'a,'b,'c,a,b,c > {
240
+ // fn foo<'d,'e,'f,d,e,f >(...) -> Self;
241
241
// }
242
242
//
243
243
// and we will create a function like
244
244
//
245
- // fn foo<'a,'b,'c,'d,'e,'f,A',B',C',D',E',F',G'>(...) -> D' {}
245
+ // fn foo<'a,'b,'c, // First the lifetime params from trait
246
+ // 'd,'e,'f, // Then lifetime params from `foo()`
247
+ // a,b,c, // Then type params from trait
248
+ // D:Trait<'a,'b,'c,a,b,c>, // Then this sucker
249
+ // E,F,G // Then type params from `foo()`, offset by 1
250
+ // >(...) -> D' {}
246
251
//
247
252
// Note that `Self` is replaced with an explicit type
248
- // parameter D' that is sandwiched in between the trait params
253
+ // parameter D that is sandwiched in between the trait params
249
254
// and the method params, and thus the indices of the method
250
255
// type parameters are offset by 1 (that is, the method
251
- // parameters are mapped from D, E, F to E' , F' , and G' ). The
256
+ // parameters are mapped from d, e, f to E, F, and G). The
252
257
// choice of this ordering is somewhat arbitrary.
253
258
//
259
+ // Note also that the bound for `D` is `Trait<'a,'b,'c,a,b,c>`.
260
+ // This implies that the lifetime parameters that were inherited
261
+ // from the trait (i.e., `'a`, `'b`, and `'c`) all must be early
262
+ // bound, since they appear in a trait bound.
263
+ //
254
264
// Also, this system is rather a hack that should be replaced
255
265
// with a more uniform treatment of Self (which is partly
256
266
// underway).
@@ -280,13 +290,17 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
280
290
} ) ;
281
291
282
292
// Convert the regions 'a, 'b, 'c defined on the trait into
283
- // bound regions on the fn.
284
- let rps_from_trait = trait_ty_generics. region_param_defs . iter ( ) . map ( |d| {
285
- ty:: ReLateBound ( m. fty . sig . binder_id ,
286
- ty:: BrNamed ( d. def_id , d. ident ) )
287
- } ) . collect ( ) ;
293
+ // bound regions on the fn. Note that because these appear in the
294
+ // bound for `Self` they must be early bound.
295
+ let new_early_region_param_defs = trait_ty_generics. region_param_defs ;
296
+ let rps_from_trait =
297
+ trait_ty_generics. region_param_defs . iter ( ) .
298
+ enumerate ( ) .
299
+ map ( |( index, d) | ty:: ReEarlyBound ( d. def_id . node , index, d. ident ) ) .
300
+ collect ( ) ;
288
301
289
302
// build up the substitution from
303
+ // 'a,'b,'c => 'a,'b,'c
290
304
// A,B,C => A',B',C'
291
305
// Self => D'
292
306
// D,E,F => E',F',G'
@@ -336,7 +350,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
336
350
ty_param_bounds_and_ty {
337
351
generics : ty:: Generics {
338
352
type_param_defs : @new_type_param_defs,
339
- region_param_defs : @ [ ] , // fn items
353
+ region_param_defs : new_early_region_param_defs
340
354
} ,
341
355
ty : ty
342
356
} ) ;
0 commit comments