about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-04-18 11:33:52 +0100
committervarkor <github@varkor.com>2018-05-15 14:21:31 +0100
commit7b45a892a482f70ccb696abdcab089cce5f2d612 (patch)
tree2da5ebfd54fd43009d597869a511557b3ae875f8
parenta17896a3b69bfea821e4cf4c3c5c67d128cdbf47 (diff)
downloadrust-7b45a892a482f70ccb696abdcab089cce5f2d612.tar.gz
rust-7b45a892a482f70ccb696abdcab089cce5f2d612.zip
Use GenericParamCount instead of FxHashMap
-rw-r--r--src/librustc/hir/lowering.rs3
-rw-r--r--src/librustc/traits/object_safety.rs4
-rw-r--r--src/librustc/ty/mod.rs39
-rw-r--r--src/librustc/util/ppaux.rs22
-rw-r--r--src/librustc_mir/monomorphize/collector.rs2
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs4
-rw-r--r--src/librustc_trans/debuginfo/mod.rs8
-rw-r--r--src/librustc_typeck/astconv.rs6
-rw-r--r--src/librustc_typeck/check/compare_method.rs10
-rw-r--r--src/librustc_typeck/check/intrinsic.rs6
-rw-r--r--src/librustc_typeck/check/method/confirm.rs4
-rw-r--r--src/librustc_typeck/check/mod.rs27
-rw-r--r--src/librustdoc/clean/mod.rs35
13 files changed, 81 insertions, 89 deletions
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index c780d1b72f2..77c2dd219c4 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -46,7 +46,6 @@ use hir::HirVec;
 use hir::map::{DefKey, DefPathData, Definitions};
 use hir::def_id::{DefId, DefIndex, DefIndexAddressSpace, CRATE_DEF_INDEX};
 use hir::def::{Def, PathResolution};
-use ty::Kind;
 use lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES};
 use middle::cstore::CrateStore;
 use rustc_data_structures::indexed_vec::IndexVec;
@@ -1462,7 +1461,7 @@ impl<'a> LoweringContext<'a> {
                         assert!(!def_id.is_local());
                         let item_generics =
                             self.cstore.item_generics_cloned_untracked(def_id, self.sess);
-                        let n = item_generics.param_counts()[&Kind::Lifetime];
+                        let n = item_generics.param_counts().lifetimes;
                         self.type_def_lifetime_params.insert(def_id, n);
                         n
                     });
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index cb8ff674188..d659d235cd1 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -21,7 +21,7 @@ use super::elaborate_predicates;
 
 use hir::def_id::DefId;
 use traits;
-use ty::{self, Ty, TyCtxt, Kind, TypeFoldable};
+use ty::{self, Ty, TyCtxt, TypeFoldable};
 use ty::subst::Substs;
 use ty::util::ExplicitSelf;
 use std::borrow::Cow;
@@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         }
 
         // We can't monomorphize things like `fn foo<A>(...)`.
-        if self.generics_of(method.def_id).param_counts()[&Kind::Type] != 0 {
+        if self.generics_of(method.def_id).param_counts().types != 0 {
             return Some(MethodViolationCode::Generic);
         }
 
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 03410785262..0cbee56487f 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -757,18 +757,6 @@ impl ty::EarlyBoundRegion {
     }
 }
 
-#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
-pub enum Kind {
-    Lifetime,
-    Type,
-}
-
-impl Kind {
-    pub fn iter<'a>() -> impl Iterator<Item = &'a Kind> {
-        [Kind::Lifetime, Kind::Type].into_iter()
-    }
-}
-
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum GenericParamDef {
     Lifetime(RegionParamDef),
@@ -791,6 +779,11 @@ impl GenericParamDef {
     }
 }
 
+pub struct GenericParamCount {
+    pub lifetimes: usize,
+    pub types: usize,
+}
+
 /// Information about the formal type/lifetime parameters associated
 /// with an item or method. Analogous to hir::Generics.
 ///
@@ -814,18 +807,20 @@ impl<'a, 'gcx, 'tcx> Generics {
         self.parent_count + self.params.len()
     }
 
-    pub fn param_counts(&self) -> FxHashMap<Kind, usize> {
-        let mut param_counts: FxHashMap<_, _> = FxHashMap();
-        Kind::iter().for_each(|kind| {
-            param_counts.insert(*kind, 0);
-        });
+    pub fn param_counts(&self) -> GenericParamCount {
+        // We could cache this as a property of `GenericParamCount`, but
+        // the aim is to refactor this away entirely eventually and the
+        // presence of this method will be a constant reminder.
+        let mut param_counts = GenericParamCount {
+            lifetimes: 0,
+            types: 0,
+        };
 
         for param in self.params.iter() {
-            let key = match param {
-                GenericParamDef::Type(_) => Kind::Type,
-                GenericParamDef::Lifetime(_) => Kind::Lifetime,
+            match param {
+                GenericParamDef::Lifetime(_) => param_counts.lifetimes += 1,
+                GenericParamDef::Type(_) => param_counts.types += 1,
             };
-            *param_counts.get_mut(&key).unwrap() += 1;
         }
 
         param_counts
@@ -904,7 +899,7 @@ impl<'a, 'gcx, 'tcx> Generics {
             // And it can be seen that in both cases, to move from a substs
             // offset to a generics offset you just have to offset by the
             // number of regions.
-            let type_param_offset = self.param_counts()[&Kind::Lifetime];
+            let type_param_offset = self.param_counts().lifetimes;
 
             let has_self = self.has_self && self.parent.is_none();
             let is_separated_self = type_param_offset != 0 && index == 0 && has_self;
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 0817ededfaa..ba869460252 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -19,8 +19,8 @@ use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
 use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
 use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon};
 use ty::{TyDynamic, TyInt, TyUint, TyInfer};
-use ty::{self, Ty, TyCtxt, TypeFoldable, Kind};
-use util::nodemap::{FxHashSet, FxHashMap};
+use ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount};
+use util::nodemap::FxHashSet;
 
 use std::cell::Cell;
 use std::fmt;
@@ -257,10 +257,10 @@ impl PrintContext {
         let verbose = self.is_verbose;
         let mut num_supplied_defaults = 0;
         let mut has_self = false;
-        let mut param_counts = FxHashMap();
-        Kind::iter().for_each(|kind| {
-            param_counts.insert(*kind, 0);
-        });
+        let mut param_counts = GenericParamCount {
+            lifetimes: 0,
+            types: 0,
+        };
         let mut is_value_path = false;
         let fn_trait_kind = ty::tls::with(|tcx| {
             // Unfortunately, some kinds of items (e.g., closures) don't have
@@ -314,7 +314,7 @@ impl PrintContext {
             if let Some(def_id) = generics.parent {
                 // Methods.
                 assert!(is_value_path);
-                child_types = child_param_counts[&Kind::Type];
+                child_types = child_param_counts.types;
                 generics = tcx.generics_of(def_id);
                 param_counts = generics.param_counts();
 
@@ -407,10 +407,10 @@ impl PrintContext {
             Ok(())
         };
 
-        print_regions(f, "<", 0, param_counts[&Kind::Lifetime])?;
+        print_regions(f, "<", 0, param_counts.lifetimes)?;
 
         let tps = substs.types()
-                        .take(param_counts[&Kind::Type] - num_supplied_defaults)
+                        .take(param_counts.types - num_supplied_defaults)
                         .skip(has_self as usize);
 
         for ty in tps {
@@ -442,10 +442,10 @@ impl PrintContext {
                 write!(f, "::{}", item_name)?;
             }
 
-            print_regions(f, "::<", param_counts[&Kind::Lifetime], usize::MAX)?;
+            print_regions(f, "::<", param_counts.lifetimes, usize::MAX)?;
 
             // FIXME: consider being smart with defaults here too
-            for ty in substs.types().skip(param_counts[&Kind::Type]) {
+            for ty in substs.types().skip(param_counts.types) {
                 start_or_continue(f, "::<", ", ")?;
                 ty.print_display(f, self)?;
             }
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 99a7e0abe16..92b4babe8a3 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -1108,7 +1108,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         continue;
                     }
 
-                    if tcx.generics_of(method.def_id).param_counts()[&ty::Kind::Type] != 0 {
+                    if tcx.generics_of(method.def_id).param_counts().types != 0 {
                         continue;
                     }
 
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index 58e63fe6b04..b65353e449f 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -13,7 +13,7 @@ use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_data_structures::sync::Lrc;
 
 use rustc::ty::maps::Providers;
-use rustc::ty::{self, TyCtxt, Kind};
+use rustc::ty::{self, TyCtxt};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
@@ -357,7 +357,7 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D
 
     // FIXME: when we make this a hard error, this should have its
     // own error code.
-    let message = if tcx.generics_of(def_id).param_counts()[&Kind::Type] != 0 {
+    let message = if tcx.generics_of(def_id).param_counts().types != 0 {
         format!("#[derive] can't be used on a #[repr(packed)] struct with \
                  type parameters (error E0133)")
     } else {
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index 2463e571436..0990c1f1714 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -26,7 +26,7 @@ use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArr
 use rustc::hir::TransFnAttrFlags;
 use rustc::hir::def_id::{DefId, CrateNum};
 use rustc::ty::subst::Substs;
-use rustc::ty::{Kind, GenericParamDef};
+use rustc::ty::GenericParamDef;
 
 use abi::Abi;
 use common::CodegenCx;
@@ -197,6 +197,12 @@ pub fn finalize(cx: &CodegenCx) {
     };
 }
 
+#[derive(PartialEq, Eq, Hash)]
+pub enum Kind {
+    Lifetime,
+    Type,
+}
+
 /// Creates the function-specific debug context.
 ///
 /// Returns the FunctionDebugContext for the function which holds state needed
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index d77a090de68..11003a49316 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -210,7 +210,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         let decl_generics = tcx.generics_of(def_id);
         let param_counts = decl_generics.param_counts();
         let num_types_provided = parameters.types.len();
-        let expected_num_region_params = param_counts[&ty::Kind::Lifetime];
+        let expected_num_region_params = param_counts.lifetimes;
         let supplied_num_region_params = parameters.lifetimes.len();
         if expected_num_region_params != supplied_num_region_params {
             report_lifetime_number_error(tcx, span,
@@ -223,7 +223,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
 
         // Check the number of type parameters supplied by the user.
         let type_params_offset = self_ty.is_some() as usize;
-        let ty_param_defs = param_counts[&ty::Kind::Type] - type_params_offset;
+        let ty_param_defs = param_counts.types - type_params_offset;
         if !infer_types || num_types_provided > ty_param_defs {
             check_type_argument_count(tcx,
                 span,
@@ -260,7 +260,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                 return ty;
             }
 
-            let i = i - (param_counts[&ty::Kind::Lifetime] + type_params_offset);
+            let i = i - (param_counts.lifetimes + type_params_offset);
             if i < num_types_provided {
                 // A provided type parameter.
                 self.ast_ty_to_ty(&parameters.types[i])
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index e02ba764057..c2c250249ad 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -10,7 +10,7 @@
 
 use rustc::hir::{self, ImplItemKind, TraitItemKind};
 use rustc::infer::{self, InferOk};
-use rustc::ty::{self, TyCtxt, Kind};
+use rustc::ty::{self, TyCtxt};
 use rustc::ty::util::ExplicitSelf;
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, Reveal};
 use rustc::ty::error::{ExpectedFound, TypeError};
@@ -357,8 +357,8 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 trait_to_skol_substs: &Substs<'tcx>)
                                                 -> Result<(), ErrorReported> {
     let span = tcx.sess.codemap().def_span(span);
-    let trait_params = trait_generics.param_counts()[&Kind::Lifetime];
-    let impl_params = impl_generics.param_counts()[&Kind::Lifetime];
+    let trait_params = trait_generics.param_counts().lifetimes;
+    let impl_params = impl_generics.param_counts().lifetimes;
 
     debug!("check_region_bounds_on_impl_method: \
             trait_generics={:?} \
@@ -574,8 +574,8 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                         -> Result<(), ErrorReported> {
     let impl_m_generics = tcx.generics_of(impl_m.def_id);
     let trait_m_generics = tcx.generics_of(trait_m.def_id);
-    let num_impl_m_type_params = impl_m_generics.param_counts()[&Kind::Type];
-    let num_trait_m_type_params = trait_m_generics.param_counts()[&Kind::Type];
+    let num_impl_m_type_params = impl_m_generics.param_counts().types;
+    let num_trait_m_type_params = trait_m_generics.param_counts().types;
     if num_impl_m_type_params != num_trait_m_type_params {
         let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
         let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs
index e3d7e16e15c..1817b4aba19 100644
--- a/src/librustc_typeck/check/intrinsic.rs
+++ b/src/librustc_typeck/check/intrinsic.rs
@@ -13,7 +13,7 @@
 
 use intrinsics;
 use rustc::traits::{ObligationCause, ObligationCauseCode};
-use rustc::ty::{self, TyCtxt, Ty, Kind};
+use rustc::ty::{self, TyCtxt, Ty};
 use rustc::util::nodemap::FxHashMap;
 use require_same_types;
 
@@ -45,7 +45,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     }
 
-    let i_n_tps = tcx.generics_of(def_id).param_counts()[&Kind::Type];
+    let i_n_tps = tcx.generics_of(def_id).param_counts().types;
     if i_n_tps != n_tps {
         let span = match it.node {
             hir::ForeignItemFn(_, _, ref generics) => generics.span,
@@ -346,7 +346,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     };
 
     let def_id = tcx.hir.local_def_id(it.id);
-    let i_n_tps = tcx.generics_of(def_id).param_counts()[&Kind::Type];
+    let i_n_tps = tcx.generics_of(def_id).param_counts().types;
     let name = it.name.as_str();
 
     let (n_tps, inputs, output) = match &*name {
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 038927bbac6..eab26046147 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -15,7 +15,7 @@ use check::{FnCtxt, PlaceOp, callee, Needs};
 use hir::def_id::DefId;
 use rustc::ty::subst::Substs;
 use rustc::traits;
-use rustc::ty::{self, Ty, Kind};
+use rustc::ty::{self, Ty};
 use rustc::ty::subst::Subst;
 use rustc::ty::adjustment::{Adjustment, Adjust, OverloadedDeref};
 use rustc::ty::adjustment::{AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
@@ -333,7 +333,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             } else if let Some(ast_ty)
                 = provided.as_ref().and_then(|p| {
                     let idx =
-                        i - parent_substs.len() - method_generics.param_counts()[&Kind::Lifetime];
+                        i - parent_substs.len() - method_generics.param_counts().lifetimes;
                     p.types.get(idx)
                 })
             {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index ad1e5ad7992..3df584040ad 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1239,8 +1239,7 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
         } else {
             for item in &m.items {
                 let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
-                let param_counts = generics.param_counts();
-                if generics.params.len() - param_counts[&ty::Kind::Lifetime] != 0 {
+                if generics.params.len() - generics.param_counts().lifetimes != 0 {
                     let mut err = struct_span_err!(tcx.sess, item.span, E0044,
                         "foreign items may not have type parameters");
                     err.span_label(item.span, "can't have type parameters");
@@ -4800,7 +4799,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
             // Skip over the lifetimes in the same segment.
             if let Some((_, generics)) = segment {
-                i -= generics.param_counts()[&ty::Kind::Lifetime];
+                i -= generics.param_counts().lifetimes;
             }
 
             if let Some(ast_ty) = types.get(i) {
@@ -4921,15 +4920,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // Check provided parameters.
         let (ty_non_def_req_len, ty_req_len, lt_req_len) =
             segment.map_or((0, 0, 0), |(_, generics)| {
-                let params_count = generics.param_counts();
+                let param_counts = generics.param_counts();
 
                 let type_params_offset
                     = (generics.parent.is_none() && generics.has_self) as usize;
-                let type_params = params_count[&ty::Kind::Type] - type_params_offset;
+                let type_params = param_counts.types - type_params_offset;
                 let type_params_barring_defaults =
                     generics.type_params_without_defaults() - type_params_offset;
 
-                (type_params_barring_defaults, type_params, params_count[&ty::Kind::Lifetime])
+                (type_params_barring_defaults, type_params, param_counts.lifetimes)
             });
 
         if types.len() > ty_req_len {
@@ -5088,22 +5087,12 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     if generics.ty_params().next().is_none() { return; }
     let mut tps_used = vec![false; generics.ty_params().count()];
 
-    let mut param_counts = FxHashMap();
-    param_counts.insert(ty::Kind::Type, 0);
-    param_counts.insert(ty::Kind::Lifetime, 0);
-
-    for param in generics.params.iter() {
-        let key = match param {
-            hir::GenericParam::Type(_) => ty::Kind::Type,
-            hir::GenericParam::Lifetime(_) => ty::Kind::Lifetime,
-        };
-        *param_counts.get_mut(&key).unwrap() += 1;
-    }
+    let lifetime_count = generics.lifetimes().count();
 
     for leaf_ty in ty.walk() {
-        if let ty::TyParam(ty::ParamTy {idx, .. }) = leaf_ty.sty {
+        if let ty::TyParam(ty::ParamTy {idx, ..}) = leaf_ty.sty {
             debug!("Found use of ty param num {}", idx);
-            tps_used[idx as usize - param_counts[&ty::Kind::Lifetime]] = true;
+            tps_used[idx as usize - lifetime_count] = true;
         } else if let ty::TyError = leaf_ty.sty {
             // If there already another error, do not emit an error for not using a type Parameter
             assert!(tcx.sess.err_count() > 0);
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 667d7f1e160..5146a29d4e3 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -41,7 +41,7 @@ use rustc::hir::def::{self, Def, CtorKind};
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::hir::def_id::DefIndexAddressSpace;
 use rustc::ty::subst::Substs;
-use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind, Kind};
+use rustc::ty::{self, TyCtxt, Region, RegionVid, Ty, AdtKind, GenericParamCount};
 use rustc::middle::stability;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
 use rustc_typeck::hir_ty_to_ty;
@@ -2684,31 +2684,34 @@ impl Clean<Type> for hir::Ty {
                     let mut ty_substs = FxHashMap();
                     let mut lt_substs = FxHashMap();
                     provided_params.with_parameters(|provided_params| {
-                        let mut indices = FxHashMap();
+                        let mut indices = GenericParamCount {
+                            lifetimes: 0,
+                            types: 0
+                        };
                         for param in generics.params.iter() {
                             match param {
+                                hir::GenericParam::Lifetime(lt_param) => {
+                                    if let Some(lt) = provided_params.lifetimes
+                                        .get(indices.lifetimes).cloned() {
+                                        if !lt.is_elided() {
+                                            let lt_def_id =
+                                                cx.tcx.hir.local_def_id(lt_param.lifetime.id);
+                                            lt_substs.insert(lt_def_id, lt.clean(cx));
+                                        }
+                                    }
+                                    indices.lifetimes += 1;
+                                }
                                 hir::GenericParam::Type(ty_param) => {
-                                    let i = indices.entry(Kind::Type).or_insert(0);
                                     let ty_param_def =
                                         Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
-                                    if let Some(ty) = provided_params.types.get(*i).cloned() {
+                                    if let Some(ty) = provided_params.types
+                                        .get(indices.types).cloned() {
                                         ty_substs.insert(ty_param_def, ty.into_inner().clean(cx));
                                     } else if let Some(default) = ty_param.default.clone() {
                                         ty_substs.insert(ty_param_def,
                                                          default.into_inner().clean(cx));
                                     }
-                                    *i += 1;
-                                }
-                                hir::GenericParam::Lifetime(lt_param) => {
-                                    let i = indices.entry(Kind::Type).or_insert(0);
-                                    if let Some(lt) = provided_params.lifetimes.get(*i).cloned() {
-                                        if !lt.is_elided() {
-                                            let lt_def_id =
-                                                cx.tcx.hir.local_def_id(lt_param.lifetime.id);
-                                            lt_substs.insert(lt_def_id, lt.clean(cx));
-                                        }
-                                    }
-                                    *i += 1;
+                                    indices.types += 1;
                                 }
                             }
                         }