@@ -236,13 +236,18 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
236236 trait_ty_generics : & ty:: Generics ) {
237237 // If declaration is
238238 //
239- // trait<'a,'b,'c,A,B,C> {
239+ // trait Trait <'a,'b,'c,A,B,C> {
240240 // fn foo<'d,'e,'f,D,E,F>(...) -> Self;
241241 // }
242242 //
243243 // and we will create a function like
244244 //
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' {}
246251 //
247252 // Note that `Self` is replaced with an explicit type
248253 // parameter D' that is sandwiched in between the trait params
@@ -251,6 +256,11 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
251256 // parameters are mapped from D, E, F to E', F', and G'). The
252257 // choice of this ordering is somewhat arbitrary.
253258 //
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+ //
254264 // Also, this system is rather a hack that should be replaced
255265 // with a more uniform treatment of Self (which is partly
256266 // underway).
@@ -280,13 +290,17 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
280290 } ) ;
281291
282292 // 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 ( ) ;
288301
289302 // build up the substitution from
303+ // 'a,'b,'c => 'a,'b,'c
290304 // A,B,C => A',B',C'
291305 // Self => D'
292306 // D,E,F => E',F',G'
@@ -336,7 +350,7 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
336350 ty_param_bounds_and_ty {
337351 generics : ty:: Generics {
338352 type_param_defs : @new_type_param_defs,
339- region_param_defs : @ [ ] , // fn items
353+ region_param_defs : new_early_region_param_defs
340354 } ,
341355 ty : ty
342356 } ) ;
0 commit comments