@@ -213,18 +213,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
213
213
// If the type is parameterized by this region, then replace this
214
214
// region with the current anon region binding (in other words,
215
215
// whatever & would get replaced with).
216
-
217
- // FIXME(varkor): Separating out the parameters is messy.
218
- let lifetimes: Vec < _ > = generic_args. args . iter ( ) . filter_map ( |arg| match arg {
219
- GenericArg :: Lifetime ( lt) => Some ( lt) ,
220
- _ => None ,
221
- } ) . collect ( ) ;
222
- let types: Vec < _ > = generic_args. args . iter ( ) . filter_map ( |arg| match arg {
223
- GenericArg :: Type ( ty) => Some ( ty) ,
224
- _ => None ,
225
- } ) . collect ( ) ;
226
- let lt_provided = lifetimes. len ( ) ;
227
- let ty_provided = types. len ( ) ;
216
+ let mut lt_provided = 0 ;
217
+ let mut ty_provided = 0 ;
218
+ for arg in & generic_args. args {
219
+ match arg {
220
+ GenericArg :: Lifetime ( _) => lt_provided += 1 ,
221
+ GenericArg :: Type ( _) => ty_provided += 1 ,
222
+ }
223
+ }
228
224
229
225
let decl_generics = tcx. generics_of ( def_id) ;
230
226
let mut lt_accepted = 0 ;
@@ -274,30 +270,44 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
274
270
false
275
271
} ;
276
272
277
- let own_self = self_ty. is_some ( ) as usize ;
273
+ let self_offset = self_ty. is_some ( ) as usize ;
278
274
let substs = Substs :: for_item ( tcx, def_id, |param, substs| {
279
- match param. kind {
280
- GenericParamDefKind :: Lifetime => {
281
- let i = param. index as usize - own_self;
282
- if let Some ( lt) = lifetimes. get ( i) {
283
- self . ast_region_to_region ( lt, Some ( param) ) . into ( )
284
- } else {
285
- tcx. types . re_static . into ( )
275
+ if param. index == 0 {
276
+ if let Some ( ty) = self_ty {
277
+ if let GenericParamDefKind :: Type { .. } = param. kind {
278
+ // Handle `Self` first.
279
+ return ty. into ( ) ;
286
280
}
287
281
}
288
- GenericParamDefKind :: Type { has_default, .. } => {
289
- let i = param. index as usize ;
282
+ }
290
283
291
- // Handle Self first, so we can adjust the index to match the AST.
292
- if let ( 0 , Some ( ty) ) = ( i, self_ty) {
293
- return ty. into ( ) ;
284
+ let inferred_lifetimes = if lt_provided == 0 {
285
+ lt_accepted
286
+ } else {
287
+ 0
288
+ } ;
289
+
290
+ let param_idx = ( param. index as usize - self_offset) . saturating_sub ( inferred_lifetimes) ;
291
+
292
+ if let Some ( arg) = generic_args. args . get ( param_idx) {
293
+ match param. kind {
294
+ GenericParamDefKind :: Lifetime => match arg {
295
+ GenericArg :: Lifetime ( lt) => {
296
+ return self . ast_region_to_region ( lt, Some ( param) ) . into ( ) ;
297
+ }
298
+ _ => { }
299
+ }
300
+ GenericParamDefKind :: Type { .. } => match arg {
301
+ GenericArg :: Type ( ty) => return self . ast_ty_to_ty ( ty) . into ( ) ,
302
+ _ => { }
294
303
}
304
+ }
305
+ }
295
306
296
- let i = i - ( lt_accepted + own_self) ;
297
- if i < ty_provided {
298
- // A provided type parameter.
299
- self . ast_ty_to_ty ( & types[ i] ) . into ( )
300
- } else if infer_types {
307
+ match param. kind {
308
+ GenericParamDefKind :: Lifetime => tcx. types . re_static . into ( ) ,
309
+ GenericParamDefKind :: Type { has_default, .. } => {
310
+ if infer_types {
301
311
// No type parameters were provided, we can infer all.
302
312
if !default_needs_object_self ( param) {
303
313
self . ty_infer_for_def ( param, span) . into ( )
@@ -314,9 +324,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
314
324
// careful!
315
325
if default_needs_object_self ( param) {
316
326
struct_span_err ! ( tcx. sess, span, E0393 ,
317
- "the type parameter `{}` must be explicitly \
318
- specified",
319
- param. name)
327
+ "the type parameter `{}` must be explicitly \
328
+ specified",
329
+ param. name)
320
330
. span_label ( span,
321
331
format ! ( "missing reference to `{}`" , param. name) )
322
332
. note ( & format ! ( "because of the default `Self` reference, \
0 commit comments