about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ich/impls_ty.rs32
-rw-r--r--src/librustc/infer/canonical.rs10
-rw-r--r--src/librustc/infer/mod.rs2
-rw-r--r--src/librustc/middle/resolve_lifetime.rs18
-rw-r--r--src/librustc/traits/error_reporting.rs14
-rw-r--r--src/librustc/traits/mod.rs2
-rw-r--r--src/librustc/traits/on_unimplemented.rs2
-rw-r--r--src/librustc/traits/select.rs14
-rw-r--r--src/librustc/traits/util.rs10
-rw-r--r--src/librustc/ty/context.rs14
-rw-r--r--src/librustc/ty/instance.rs3
-rw-r--r--src/librustc/ty/mod.rs25
-rw-r--r--src/librustc/ty/relate.rs7
-rw-r--r--src/librustc/ty/sty.rs40
-rw-r--r--src/librustc/ty/subst.rs119
-rw-r--r--src/librustc/ty/util.rs2
-rw-r--r--src/librustc/util/ppaux.rs6
-rw-r--r--src/librustc_codegen_llvm/base.rs3
-rw-r--r--src/librustc_codegen_llvm/common.rs6
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/universal_regions.rs2
-rw-r--r--src/librustc_mir/build/matches/test.rs2
-rw-r--r--src/librustc_mir/hair/cx/mod.rs4
-rw-r--r--src/librustc_mir/monomorphize/collector.rs6
-rw-r--r--src/librustc_mir/monomorphize/mod.rs8
-rw-r--r--src/librustc_mir/shim.rs6
-rw-r--r--src/librustc_mir/transform/generator.rs6
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs6
-rw-r--r--src/librustc_privacy/lib.rs8
-rw-r--r--src/librustc_traits/lowering.rs8
-rw-r--r--src/librustc_typeck/astconv.rs55
-rw-r--r--src/librustc_typeck/check/closure.rs2
-rw-r--r--src/librustc_typeck/check/coercion.rs2
-rw-r--r--src/librustc_typeck/check/compare_method.rs4
-rw-r--r--src/librustc_typeck/check/method/confirm.rs2
-rw-r--r--src/librustc_typeck/check/method/mod.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs4
-rw-r--r--src/librustc_typeck/check/method/suggest.rs5
-rw-r--r--src/librustc_typeck/check/mod.rs27
-rw-r--r--src/librustc_typeck/check/wfcheck.rs10
-rw-r--r--src/librustc_typeck/coherence/builtin.rs2
-rw-r--r--src/librustc_typeck/collect.rs16
-rw-r--r--src/librustc_typeck/impl_wf_check.rs2
-rw-r--r--src/librustdoc/clean/auto_trait.rs2
-rw-r--r--src/librustdoc/clean/mod.rs4
45 files changed, 246 insertions, 281 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index 1b16d93ef27..edd9f0fab51 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -739,8 +739,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::Generics {
             ref parent_count,
             ref params,
 
-            // Reverse map to each `TypeParamDef`'s `index` field, from
-            // `def_id.index` (`def_id.krate` is the same as the item's).
+            // Reverse map to each param's `index` field, from its `def_id`.
             param_def_id_to_index: _, // Don't hash this
             has_self,
             has_late_bound_regions,
@@ -754,11 +753,6 @@ impl<'a> HashStable<StableHashingContext<'a>> for ty::Generics {
     }
 }
 
-impl_stable_hash_for!(enum ty::GenericParamDefKind {
-    Lifetime,
-    Type(ty)
-});
-
 impl_stable_hash_for!(struct ty::GenericParamDef {
     name,
     def_id,
@@ -767,11 +761,25 @@ impl_stable_hash_for!(struct ty::GenericParamDef {
     kind
 });
 
-impl_stable_hash_for!(struct ty::TypeParamDef {
-    has_default,
-    object_lifetime_default,
-    synthetic
-});
+impl<'a> HashStable<StableHashingContext<'a>> for ty::GenericParamDefKind {
+    fn hash_stable<W: StableHasherResult>(&self,
+                                          hcx: &mut StableHashingContext<'a>,
+                                          hasher: &mut StableHasher<W>) {
+        mem::discriminant(self).hash_stable(hcx, hasher);
+        match *self {
+            ty::GenericParamDefKind::Lifetime => {}
+            ty::GenericParamDefKind::Type {
+                has_default,
+                ref object_lifetime_default,
+                ref synthetic,
+            } => {
+                has_default.hash_stable(hcx, hasher);
+                object_lifetime_default.hash_stable(hcx, hasher);
+                synthetic.hash_stable(hcx, hasher);
+            }
+        }
+    }
+}
 
 impl<'a, 'gcx, T> HashStable<StableHashingContext<'a>>
 for ::middle::resolve_lifetime::Set1<T>
diff --git a/src/librustc/infer/canonical.rs b/src/librustc/infer/canonical.rs
index 4bb191a878f..1164c332330 100644
--- a/src/librustc/infer/canonical.rs
+++ b/src/librustc/infer/canonical.rs
@@ -256,11 +256,11 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
 
                     CanonicalTyVarKind::Float => self.tcx.mk_float_var(self.next_float_var_id()),
                 };
-                Kind::from(ty)
+                ty.into()
             }
 
             CanonicalVarKind::Region => {
-                Kind::from(self.next_region_var(RegionVariableOrigin::MiscVariable(span)))
+                self.next_region_var(RegionVariableOrigin::MiscVariable(span)).into()
             }
         }
     }
@@ -555,7 +555,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
                      opportunistically resolved to {:?}",
                     vid, r
                 );
-                let cvar = self.canonical_var(info, Kind::from(r));
+                let cvar = self.canonical_var(info, r.into());
                 self.tcx().mk_region(ty::ReCanonical(cvar))
             }
 
@@ -570,7 +570,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
                     let info = CanonicalVarInfo {
                         kind: CanonicalVarKind::Region,
                     };
-                    let cvar = self.canonical_var(info, Kind::from(r));
+                    let cvar = self.canonical_var(info, r.into());
                     self.tcx().mk_region(ty::ReCanonical(cvar))
                 } else {
                     r
@@ -750,7 +750,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
             let info = CanonicalVarInfo {
                 kind: CanonicalVarKind::Ty(ty_kind),
             };
-            let cvar = self.canonical_var(info, Kind::from(ty_var));
+            let cvar = self.canonical_var(info, ty_var.into());
             self.tcx().mk_infer(ty::InferTy::CanonicalTy(cvar))
         }
     }
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index f105ecf7ee4..6b31f869ef9 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -915,7 +915,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 // region parameter definition.
                 self.next_region_var(EarlyBoundRegion(span, param.name)).into()
             }
-            GenericParamDefKind::Type(_) => {
+            GenericParamDefKind::Type {..} => {
                 // Create a type inference variable for the given
                 // type parameter definition. The substitutions are
                 // for actual parameters that may be referred to by
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 900fbdfdead..5f150ba1e2d 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -1658,18 +1658,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
                 self.xcrate_object_lifetime_defaults
                     .entry(def_id)
                     .or_insert_with(|| {
-                        tcx.generics_of(def_id)
-                            .params
-                            .iter()
-                            .filter_map(|param| {
-                                match param.kind {
-                                    GenericParamDefKind::Type(ty) => {
-                                        Some(ty.object_lifetime_default)
-                                    }
-                                    GenericParamDefKind::Lifetime => None,
+                        tcx.generics_of(def_id).params.iter().filter_map(|param| {
+                            match param.kind {
+                                GenericParamDefKind::Type { object_lifetime_default, .. } => {
+                                    Some(object_lifetime_default)
                                 }
-                            })
-                            .collect()
+                                GenericParamDefKind::Lifetime => None,
+                            }
+                        }).collect()
                     })
             };
             unsubst
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 97ce730c59e..49aee8bcd01 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -383,7 +383,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 
         for param in generics.params.iter() {
             let value = match param.kind {
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type {..} => {
                     trait_ref.substs[param.index as usize].to_string()
                 },
                 GenericParamDefKind::Lifetime => continue,
@@ -652,14 +652,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             && fallback_has_occurred
                         {
                             let predicate = trait_predicate.map_bound(|mut trait_pred| {
-                                {
-                                    let trait_ref = &mut trait_pred.trait_ref;
-                                    let never_substs = trait_ref.substs;
-                                    let mut unit_substs = Vec::with_capacity(never_substs.len());
-                                    unit_substs.push(self.tcx.mk_nil().into());
-                                    unit_substs.extend(&never_substs[1..]);
-                                    trait_ref.substs = self.tcx.intern_substs(&unit_substs);
-                                }
+                                trait_pred.trait_ref.substs = self.tcx.mk_substs_trait(
+                                    self.tcx.mk_nil(),
+                                    &trait_pred.trait_ref.substs[1..],
+                                );
                                 trait_pred
                             });
                             let unit_obligation = Obligation {
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index b5115eab7dc..d846b23d20d 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -838,7 +838,7 @@ fn vtable_methods<'a, 'tcx>(
                     Substs::for_item(tcx, def_id, |param, _| {
                         match param.kind {
                             GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
-                            GenericParamDefKind::Type(_) => {
+                            GenericParamDefKind::Type {..} => {
                                 trait_ref.substs[param.index as usize]
                             }
                         }
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 539f40cf3ef..0550cf7c6d2 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -289,7 +289,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
         let generics = tcx.generics_of(trait_ref.def_id);
         let generic_map = generics.params.iter().filter_map(|param| {
             let value = match param.kind {
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type {..} => {
                     trait_ref.substs[param.index as usize].to_string()
                 },
                 GenericParamDefKind::Lifetime => return None
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index bd7ec4a12b0..c3b5b8e6fb3 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -37,7 +37,7 @@ use dep_graph::{DepNodeIndex, DepKind};
 use hir::def_id::DefId;
 use infer;
 use infer::{InferCtxt, InferOk, TypeFreshener};
-use ty::subst::{Kind, Subst, Substs};
+use ty::subst::{Subst, Substs};
 use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
 use ty::fast_reject;
 use ty::relate::TypeRelation;
@@ -3019,7 +3019,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 // with a potentially unsized trailing field.
                 let params = substs_a.iter().enumerate().map(|(i, &k)| {
                     if ty_params.contains(i) {
-                        Kind::from(tcx.types.err)
+                        tcx.types.err.into()
                     } else {
                         k
                     }
@@ -3058,7 +3058,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     obligation.predicate.def_id(),
                     obligation.recursion_depth + 1,
                     inner_source,
-                    &[inner_target]));
+                    &[inner_target.into()]));
             }
 
             // (.., T) -> (.., U).
@@ -3066,16 +3066,16 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                 assert_eq!(tys_a.len(), tys_b.len());
 
                 // The last field of the tuple has to exist.
-                let (a_last, a_mid) = if let Some(x) = tys_a.split_last() {
+                let (&a_last, a_mid) = if let Some(x) = tys_a.split_last() {
                     x
                 } else {
                     return Err(Unimplemented);
                 };
-                let b_last = tys_b.last().unwrap();
+                let &b_last = tys_b.last().unwrap();
 
                 // Check that the source tuple with the target's
                 // last element is equal to the target.
-                let new_tuple = tcx.mk_tup(a_mid.iter().chain(Some(b_last)));
+                let new_tuple = tcx.mk_tup(a_mid.iter().cloned().chain(iter::once(b_last)));
                 let InferOk { obligations, .. } =
                     self.infcx.at(&obligation.cause, obligation.param_env)
                               .eq(target, new_tuple)
@@ -3089,7 +3089,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     obligation.predicate.def_id(),
                     obligation.recursion_depth + 1,
                     a_last,
-                    &[b_last]));
+                    &[b_last.into()]));
             }
 
             _ => bug!()
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index f5a9d2a7f00..684022f8e8a 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use hir::def_id::DefId;
-use ty::subst::{Subst, Substs};
+use ty::subst::{Kind, Subst, Substs};
 use ty::{self, Ty, TyCtxt, ToPredicate, ToPolyTraitRef};
 use ty::outlives::Component;
 use util::nodemap::FxHashSet;
@@ -430,13 +430,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                                    cause: ObligationCause<'tcx>,
                                    trait_def_id: DefId,
                                    recursion_depth: usize,
-                                   param_ty: Ty<'tcx>,
-                                   ty_params: &[Ty<'tcx>])
+                                   self_ty: Ty<'tcx>,
+                                   params: &[Kind<'tcx>])
         -> PredicateObligation<'tcx>
     {
         let trait_ref = ty::TraitRef {
             def_id: trait_def_id,
-            substs: self.mk_substs_trait(param_ty, ty_params)
+            substs: self.mk_substs_trait(self_ty, params)
         };
         predicate_for_trait_ref(cause, param_env, trait_ref, recursion_depth)
     }
@@ -512,7 +512,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         };
         let trait_ref = ty::TraitRef {
             def_id: fn_trait_def_id,
-            substs: self.mk_substs_trait(self_ty, &[arguments_tuple]),
+            substs: self.mk_substs_trait(self_ty, &[arguments_tuple.into()]),
         };
         ty::Binder::bind((trait_ref, sig.skip_binder().output()))
     }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ee55b8dd767..a3d380c3e14 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -2329,11 +2329,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         let substs = Substs::for_item(self, def_id, |param, substs| {
             match param.kind {
                 GenericParamDefKind::Lifetime => bug!(),
-                GenericParamDefKind::Type(ty_param) => {
+                GenericParamDefKind::Type { has_default, .. } => {
                     if param.index == 0 {
                         ty.into()
                     } else {
-                        assert!(ty_param.has_default);
+                        assert!(has_default);
                         self.type_of(param.def_id).subst(self, substs).into()
                     }
                 }
@@ -2477,7 +2477,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             GenericParamDefKind::Lifetime => {
                 self.mk_region(ty::ReEarlyBound(param.to_early_bound_region_data())).into()
             }
-            GenericParamDefKind::Type(_) => self.mk_ty_param(param.index, param.name).into(),
+            GenericParamDefKind::Type {..} => self.mk_ty_param(param.index, param.name).into(),
         }
     }
 
@@ -2584,11 +2584,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn mk_substs_trait(self,
-                     s: Ty<'tcx>,
-                     t: &[Ty<'tcx>])
+                     self_ty: Ty<'tcx>,
+                     rest: &[Kind<'tcx>])
                     -> &'tcx Substs<'tcx>
     {
-        self.mk_substs(iter::once(s).chain(t.into_iter().cloned()).map(Kind::from))
+        self.mk_substs(iter::once(self_ty.into()).chain(rest.iter().cloned()))
     }
 
     pub fn mk_clauses<I: InternAs<[Clause<'tcx>], Clauses<'tcx>>>(self, iter: I) -> I::Output {
@@ -2600,7 +2600,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn mk_goal(self, goal: Goal<'tcx>) -> &'tcx Goal {
-        &self.mk_goals(iter::once(goal))[0]
+        &self.intern_goals(&[goal])[0]
     }
 
     pub fn lint_node<S: Into<MultiSpan>>(self,
diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs
index e97f782fccf..66edbeff749 100644
--- a/src/librustc/ty/instance.rs
+++ b/src/librustc/ty/instance.rs
@@ -10,7 +10,6 @@
 
 use hir::def_id::DefId;
 use ty::{self, Ty, TypeFoldable, Substs, TyCtxt};
-use ty::subst::Kind;
 use traits;
 use rustc_target::spec::abi::Abi;
 use util::ppaux;
@@ -361,7 +360,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
     let sig = substs.closure_sig(closure_did, tcx);
     let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
     assert_eq!(sig.inputs().len(), 1);
-    let substs = tcx.mk_substs([Kind::from(self_ty), sig.inputs()[0].into()].iter().cloned());
+    let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
 
     debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
     Instance { def, substs }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index ce7feae0719..1726ed27d14 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -714,13 +714,6 @@ pub enum IntVarValue {
 #[derive(Clone, Copy, PartialEq, Eq)]
 pub struct FloatVarValue(pub ast::FloatTy);
 
-#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
-pub struct TypeParamDef {
-    pub has_default: bool,
-    pub object_lifetime_default: ObjectLifetimeDefault,
-    pub synthetic: Option<hir::SyntheticTyParamKind>,
-}
-
 impl ty::EarlyBoundRegion {
     pub fn to_bound_region(&self) -> ty::BoundRegion {
         ty::BoundRegion::BrNamed(self.def_id, self.name)
@@ -730,7 +723,11 @@ impl ty::EarlyBoundRegion {
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
 pub enum GenericParamDefKind {
     Lifetime,
-    Type(TypeParamDef),
+    Type {
+        has_default: bool,
+        object_lifetime_default: ObjectLifetimeDefault,
+        synthetic: Option<hir::SyntheticTyParamKind>,
+    }
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable)]
@@ -811,7 +808,7 @@ impl<'a, 'gcx, 'tcx> Generics {
         for param in &self.params {
             match param.kind {
                 GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
-                GenericParamDefKind::Type(_) => own_counts.types += 1,
+                GenericParamDefKind::Type {..} => own_counts.types += 1,
             };
         }
 
@@ -821,7 +818,7 @@ impl<'a, 'gcx, 'tcx> Generics {
     pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
         for param in &self.params {
             match param.kind {
-                GenericParamDefKind::Type(_) => return true,
+                GenericParamDefKind::Type {..} => return true,
                 GenericParamDefKind::Lifetime => {}
             }
         }
@@ -850,7 +847,7 @@ impl<'a, 'gcx, 'tcx> Generics {
         }
     }
 
-    /// Returns the `TypeParamDef` associated with this `ParamTy`.
+    /// Returns the `GenericParamDef` associated with this `ParamTy`.
     pub fn type_param(&'tcx self,
                       param: &ParamTy,
                       tcx: TyCtxt<'a, 'gcx, 'tcx>)
@@ -858,7 +855,7 @@ impl<'a, 'gcx, 'tcx> Generics {
         if let Some(index) = param.idx.checked_sub(self.parent_count as u32) {
             let param = &self.params[index as usize];
             match param.kind {
-                ty::GenericParamDefKind::Type(_) => param,
+                ty::GenericParamDefKind::Type {..} => param,
                 _ => bug!("expected type parameter, but found another generic parameter")
             }
         } else {
@@ -2678,11 +2675,11 @@ fn adt_sized_constraint<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                   -> &'tcx [Ty<'tcx>] {
     let def = tcx.adt_def(def_id);
 
-    let result = tcx.intern_type_list(&def.variants.iter().flat_map(|v| {
+    let result = tcx.mk_type_list(def.variants.iter().flat_map(|v| {
         v.fields.last()
     }).flat_map(|f| {
         def.sized_constraint_for_ty(tcx, tcx.type_of(f.did))
-    }).collect::<Vec<_>>());
+    }));
 
     debug!("adt_sized_constraint: {:?} => {:?}", def, result);
 
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 4a33f1a1f54..7603ed71023 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -24,7 +24,6 @@ use std::rc::Rc;
 use std::iter;
 use rustc_target::spec::abi;
 use hir as ast;
-use rustc_data_structures::accumulate_vec::AccumulateVec;
 
 pub type RelateResult<'tcx, T> = Result<T, TypeError<'tcx>>;
 
@@ -154,6 +153,8 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
                            -> RelateResult<'tcx, ty::FnSig<'tcx>>
         where R: TypeRelation<'a, 'gcx, 'tcx>, 'gcx: 'a+'tcx, 'tcx: 'a
     {
+        let tcx = relation.tcx();
+
         if a.variadic != b.variadic {
             return Err(TypeError::VariadicMismatch(
                 expected_found(relation, &a.variadic, &b.variadic)));
@@ -175,9 +176,9 @@ impl<'tcx> Relate<'tcx> for ty::FnSig<'tcx> {
                 } else {
                     relation.relate_with_variance(ty::Contravariant, &a, &b)
                 }
-            }).collect::<Result<AccumulateVec<[_; 8]>, _>>()?;
+            });
         Ok(ty::FnSig {
-            inputs_and_output: relation.tcx().intern_type_list(&inputs_and_output),
+            inputs_and_output: tcx.mk_type_list(inputs_and_output)?,
             variadic: a.variadic,
             unsafety,
             abi,
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 0b8f10d311d..6bc0cb51a92 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -622,6 +622,18 @@ impl<'tcx> TraitRef<'tcx> {
         // associated types.
         self.substs.types()
     }
+
+    pub fn from_method(tcx: TyCtxt<'_, '_, 'tcx>,
+                       trait_id: DefId,
+                       substs: &Substs<'tcx>)
+                       -> ty::TraitRef<'tcx> {
+        let defs = tcx.generics_of(trait_id);
+
+        ty::TraitRef {
+            def_id: trait_id,
+            substs: tcx.intern_substs(&substs[..defs.params.len()])
+        }
+    }
 }
 
 pub type PolyTraitRef<'tcx> = Binder<TraitRef<'tcx>>;
@@ -663,6 +675,18 @@ impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> {
         self.substs.types()
     }
 
+    pub fn erase_self_ty(tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                         trait_ref: ty::TraitRef<'tcx>)
+                         -> ty::ExistentialTraitRef<'tcx> {
+        // Assert there is a Self.
+        trait_ref.substs.type_at(0);
+
+        ty::ExistentialTraitRef {
+            def_id: trait_ref.def_id,
+            substs: tcx.intern_substs(&trait_ref.substs[1..])
+        }
+    }
+
     /// Object types don't have a self-type specified. Therefore, when
     /// we convert the principal trait-ref into a normal trait-ref,
     /// you must give *some* self-type. A common choice is `mk_err()`
@@ -674,8 +698,7 @@ impl<'a, 'gcx, 'tcx> ExistentialTraitRef<'tcx> {
 
         ty::TraitRef {
             def_id: self.def_id,
-            substs: tcx.mk_substs(
-                iter::once(self_ty.into()).chain(self.substs.iter().cloned()))
+            substs: tcx.mk_substs_trait(self_ty, self.substs)
         }
     }
 }
@@ -686,6 +709,16 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> {
     pub fn def_id(&self) -> DefId {
         self.skip_binder().def_id
     }
+
+    /// Object types don't have a self-type specified. Therefore, when
+    /// we convert the principal trait-ref into a normal trait-ref,
+    /// you must give *some* self-type. A common choice is `mk_err()`
+    /// or some skolemized type.
+    pub fn with_self_ty(&self, tcx: TyCtxt<'_, '_, 'tcx>,
+                        self_ty: Ty<'tcx>)
+                        -> ty::PolyTraitRef<'tcx>  {
+        self.map_bound(|trait_ref| trait_ref.with_self_ty(tcx, self_ty))
+    }
 }
 
 /// Binder is a binder for higher-ranked lifetimes. It is part of the
@@ -1188,8 +1221,7 @@ impl<'a, 'tcx, 'gcx> ExistentialProjection<'tcx> {
         ty::ProjectionPredicate {
             projection_ty: ty::ProjectionTy {
                 item_def_id: self.item_def_id,
-                substs: tcx.mk_substs(
-                iter::once(self_ty.into()).chain(self.substs.iter().cloned())),
+                substs: tcx.mk_substs_trait(self_ty, self.substs),
             },
             ty: self.ty,
         }
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index b94b3e17f86..f44e1533f52 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -11,16 +11,16 @@
 // Type substitutions.
 
 use hir::def_id::DefId;
-use ty::{self, Lift, Slice, Region, Ty, TyCtxt};
+use ty::{self, Lift, Slice, Ty, TyCtxt};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 
 use serialize::{self, Encodable, Encoder, Decodable, Decoder};
 use syntax_pos::{Span, DUMMY_SP};
 use rustc_data_structures::accumulate_vec::AccumulateVec;
+use rustc_data_structures::array_vec::ArrayVec;
 
 use core::intrinsics;
 use std::fmt;
-use std::iter;
 use std::marker::PhantomData;
 use std::mem;
 use std::num::NonZeroUsize;
@@ -40,7 +40,7 @@ const TAG_MASK: usize = 0b11;
 const TYPE_TAG: usize = 0b00;
 const REGION_TAG: usize = 0b01;
 
-#[derive(Debug)]
+#[derive(Debug, RustcEncodable, RustcDecodable)]
 pub enum UnpackedKind<'tcx> {
     Lifetime(ty::Region<'tcx>),
     Type(Ty<'tcx>),
@@ -143,34 +143,13 @@ impl<'tcx> TypeFoldable<'tcx> for Kind<'tcx> {
 
 impl<'tcx> Encodable for Kind<'tcx> {
     fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
-        e.emit_enum("Kind", |e| {
-            match self.unpack() {
-                UnpackedKind::Lifetime(lt) => {
-                    e.emit_enum_variant("Region", REGION_TAG, 1, |e| {
-                        e.emit_enum_variant_arg(0, |e| lt.encode(e))
-                    })
-                }
-                UnpackedKind::Type(ty) => {
-                    e.emit_enum_variant("Ty", TYPE_TAG, 1, |e| {
-                        e.emit_enum_variant_arg(0, |e| ty.encode(e))
-                    })
-                }
-            }
-        })
+        self.unpack().encode(e)
     }
 }
 
 impl<'tcx> Decodable for Kind<'tcx> {
     fn decode<D: Decoder>(d: &mut D) -> Result<Kind<'tcx>, D::Error> {
-        d.read_enum("Kind", |d| {
-            d.read_enum_variant(&["Ty", "Region"], |d, tag| {
-                match tag {
-                    TYPE_TAG => Ty::decode(d).map(Kind::from),
-                    REGION_TAG => Region::decode(d).map(Kind::from),
-                    _ => Err(d.error("invalid Kind tag"))
-                }
-            })
-        })
+        Ok(UnpackedKind::decode(d)?.pack())
     }
 }
 
@@ -198,7 +177,12 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
     {
         let defs = tcx.generics_of(def_id);
-        let mut substs = Vec::with_capacity(defs.count());
+        let count = defs.count();
+        let mut substs = if count <= 8 {
+            AccumulateVec::Array(ArrayVec::new())
+        } else {
+            AccumulateVec::Heap(Vec::with_capacity(count))
+        };
         Substs::fill_item(&mut substs, tcx, defs, &mut mk_kind);
         tcx.intern_substs(&substs)
     }
@@ -210,17 +194,18 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
                         -> &'tcx Substs<'tcx>
     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
     {
-        let defs = tcx.generics_of(def_id);
-        let mut result = Vec::with_capacity(defs.count());
-        result.extend(self[..].iter().cloned());
-        Substs::fill_single(&mut result, defs, &mut mk_kind);
-        tcx.intern_substs(&result)
+        Substs::for_item(tcx, def_id, |param, substs| {
+            match self.get(param.index as usize) {
+                Some(&kind) => kind,
+                None => mk_kind(param, substs),
+            }
+        })
     }
 
-    pub fn fill_item<F>(substs: &mut Vec<Kind<'tcx>>,
-                             tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                             defs: &ty::Generics,
-                             mk_kind: &mut F)
+    fn fill_item<F>(substs: &mut AccumulateVec<[Kind<'tcx>; 8]>,
+                    tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                    defs: &ty::Generics,
+                    mk_kind: &mut F)
     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
     {
 
@@ -231,15 +216,18 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> {
         Substs::fill_single(substs, defs, mk_kind)
     }
 
-    fn fill_single<F>(substs: &mut Vec<Kind<'tcx>>,
-                           defs: &ty::Generics,
-                           mk_kind: &mut F)
+    fn fill_single<F>(substs: &mut AccumulateVec<[Kind<'tcx>; 8]>,
+                      defs: &ty::Generics,
+                      mk_kind: &mut F)
     where F: FnMut(&ty::GenericParamDef, &[Kind<'tcx>]) -> Kind<'tcx>
     {
         for param in &defs.params {
             let kind = mk_kind(param, substs);
             assert_eq!(param.index as usize, substs.len());
-            substs.push(kind);
+            match *substs {
+                AccumulateVec::Array(ref mut arr) => arr.push(kind),
+                AccumulateVec::Heap(ref mut vec) => vec.push(kind),
+            }
         }
     }
 
@@ -543,54 +531,3 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
         self.tcx().mk_region(ty::fold::shift_region(*region, self.region_binders_passed))
     }
 }
-
-// Helper methods that modify substitutions.
-
-impl<'a, 'gcx, 'tcx> ty::TraitRef<'tcx> {
-    pub fn from_method(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                       trait_id: DefId,
-                       substs: &Substs<'tcx>)
-                       -> ty::TraitRef<'tcx> {
-        let defs = tcx.generics_of(trait_id);
-
-        ty::TraitRef {
-            def_id: trait_id,
-            substs: tcx.intern_substs(&substs[..defs.params.len()])
-        }
-    }
-}
-
-impl<'a, 'gcx, 'tcx> ty::ExistentialTraitRef<'tcx> {
-    pub fn erase_self_ty(tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                         trait_ref: ty::TraitRef<'tcx>)
-                         -> ty::ExistentialTraitRef<'tcx> {
-        // Assert there is a Self.
-        trait_ref.substs.type_at(0);
-
-        ty::ExistentialTraitRef {
-            def_id: trait_ref.def_id,
-            substs: tcx.intern_substs(&trait_ref.substs[1..])
-        }
-    }
-}
-
-impl<'a, 'gcx, 'tcx> ty::PolyExistentialTraitRef<'tcx> {
-    /// Object types don't have a self-type specified. Therefore, when
-    /// we convert the principal trait-ref into a normal trait-ref,
-    /// you must give *some* self-type. A common choice is `mk_err()`
-    /// or some skolemized type.
-    pub fn with_self_ty(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-                        self_ty: Ty<'tcx>)
-                        -> ty::PolyTraitRef<'tcx>  {
-        // otherwise the escaping regions would be captured by the binder
-        assert!(!self_ty.has_escaping_regions());
-
-        self.map_bound(|trait_ref| {
-            ty::TraitRef {
-                def_id: trait_ref.def_id,
-                substs: tcx.mk_substs(
-                    iter::once(self_ty.into()).chain(trait_ref.substs.iter().cloned()))
-            }
-        })
-    }
-}
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 7cfcbcb86af..e3db4972edc 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -572,7 +572,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         Substs::for_item(self, item_def_id, |param, _| {
             match param.kind {
                 GenericParamDefKind::Lifetime => self.types.re_erased.into(),
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type {..} => {
                     bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
                 }
             }
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index b8345b6c2d9..82afce415a7 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -337,7 +337,9 @@ impl PrintContext {
                 let mut type_params =
                     generics.params.iter().rev().filter_map(|param| {
                         match param.kind {
-                            GenericParamDefKind::Type(ty) => Some((param.def_id, ty.has_default)),
+                            GenericParamDefKind::Type { has_default, .. } => {
+                                Some((param.def_id, has_default))
+                            }
                             GenericParamDefKind::Lifetime => None,
                         }
                     }).peekable();
@@ -604,7 +606,7 @@ impl fmt::Debug for ty::GenericParamDef {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let type_name = match self.kind {
             ty::GenericParamDefKind::Lifetime => "Lifetime",
-            ty::GenericParamDefKind::Type(_) => "Type",
+            ty::GenericParamDefKind::Type {..} => "Type",
         };
         write!(f, "{}({}, {:?}, {})",
                type_name,
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index d04cb72d52d..59d227557ae 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -43,7 +43,6 @@ use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::{self, Align, TyLayout, LayoutOf};
 use rustc::ty::maps::Providers;
 use rustc::dep_graph::{DepNode, DepConstructor};
-use rustc::ty::subst::Kind;
 use rustc::middle::cstore::{self, LinkMeta, LinkagePreference};
 use rustc::middle::exported_symbols;
 use rustc::util::common::{time, print_time_passes_entry};
@@ -595,7 +594,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
             let start_fn = callee::resolve_and_get_fn(
                 cx,
                 start_def_id,
-                cx.tcx.intern_substs(&[Kind::from(main_ret_ty)]),
+                cx.tcx.intern_substs(&[main_ret_ty.into()]),
             );
             (start_fn, vec![bx.pointercast(rust_main, Type::i8p(cx).ptr_to()),
                             arg_argc, arg_argv])
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 10ca8e43ce6..6a4b87ced15 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -431,8 +431,10 @@ pub fn ty_fn_sig<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
             sig.map_bound(|sig| {
                 let state_did = tcx.lang_items().gen_state().unwrap();
                 let state_adt_ref = tcx.adt_def(state_did);
-                let state_substs = tcx.mk_substs([sig.yield_ty.into(),
-                    sig.return_ty.into()].iter());
+                let state_substs = tcx.intern_substs(&[
+                    sig.yield_ty.into(),
+                    sig.return_ty.into(),
+                ]);
                 let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
 
                 tcx.mk_fn_sig(iter::once(env_ty),
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 1014299c708..456aa1aa66f 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -1375,9 +1375,10 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 }
 
                 CastKind::Unsize => {
+                    let &ty = ty;
                     let trait_ref = ty::TraitRef {
                         def_id: tcx.lang_items().coerce_unsized_trait().unwrap(),
-                        substs: tcx.mk_substs_trait(op.ty(mir, tcx), &[ty]),
+                        substs: tcx.mk_substs_trait(op.ty(mir, tcx), &[ty.into()]),
                     };
 
                     self.prove_trait_ref(trait_ref, location);
diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs
index 52ebf38c668..2bb96a856ce 100644
--- a/src/librustc_mir/borrow_check/nll/universal_regions.rs
+++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs
@@ -669,7 +669,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
                 assert_eq!(self.mir_def_id, def_id);
                 let ty = tcx.type_of(def_id);
                 let ty = indices.fold_to_region_vids(tcx, &ty);
-                ty::Binder::dummy(tcx.mk_type_list(iter::once(ty)))
+                ty::Binder::dummy(tcx.intern_type_list(&[ty]))
             }
         }
     }
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 913cb944835..5dbe8d850bd 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -312,7 +312,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                         },
                     }
                     let eq_def_id = self.hir.tcx().lang_items().eq_trait().unwrap();
-                    let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty]);
+                    let (mty, method) = self.hir.trait_method(eq_def_id, "eq", ty, &[ty.into()]);
 
                     // take the argument by reference
                     let region_scope = self.topmost_scope();
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index 4739c0e92ed..71dd35c010d 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -24,7 +24,7 @@ use rustc::infer::InferCtxt;
 use rustc::ty::layout::{IntegerExt, Size};
 use rustc::ty::subst::Subst;
 use rustc::ty::{self, Ty, TyCtxt, layout};
-use rustc::ty::subst::Substs;
+use rustc::ty::subst::{Kind, Substs};
 use syntax::ast::{self, LitKind};
 use syntax::attr;
 use syntax::symbol::Symbol;
@@ -235,7 +235,7 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
                         trait_def_id: DefId,
                         method_name: &str,
                         self_ty: Ty<'tcx>,
-                        params: &[Ty<'tcx>])
+                        params: &[Kind<'tcx>])
                         -> (Ty<'tcx>, Literal<'tcx>) {
         let method_name = Symbol::intern(method_name);
         let substs = self.tcx.mk_substs_trait(self_ty, params);
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 100edd6b4ff..148b12cdc31 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -196,7 +196,7 @@ use rustc::hir::def_id::DefId;
 use rustc::middle::const_val::ConstVal;
 use rustc::mir::interpret::{AllocId, ConstValue};
 use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
-use rustc::ty::subst::{Substs, Kind};
+use rustc::ty::subst::Substs;
 use rustc::ty::{self, TypeFoldable, Ty, TyCtxt, GenericParamDefKind};
 use rustc::ty::adjustment::CustomCoerceUnsized;
 use rustc::session::config;
@@ -1067,7 +1067,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> {
             self.tcx,
             ty::ParamEnv::reveal_all(),
             start_def_id,
-            self.tcx.intern_substs(&[Kind::from(main_ret_ty)])
+            self.tcx.intern_substs(&[main_ret_ty.into()])
         ).unwrap();
 
         self.output.push(create_fn_mono_item(start_instance));
@@ -1115,7 +1115,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     let substs = Substs::for_item(tcx, method.def_id, |param, _| {
                         match param.kind {
                             GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
-                            GenericParamDefKind::Type(_) => {
+                            GenericParamDefKind::Type {..} => {
                                 trait_ref.substs[param.index as usize]
                             }
                         }
diff --git a/src/librustc_mir/monomorphize/mod.rs b/src/librustc_mir/monomorphize/mod.rs
index 51793305513..bf544e5120c 100644
--- a/src/librustc_mir/monomorphize/mod.rs
+++ b/src/librustc_mir/monomorphize/mod.rs
@@ -12,7 +12,6 @@ use rustc::hir::def_id::DefId;
 use rustc::middle::lang_items::DropInPlaceFnLangItem;
 use rustc::traits;
 use rustc::ty::adjustment::CustomCoerceUnsized;
-use rustc::ty::subst::Kind;
 use rustc::ty::{self, Ty, TyCtxt};
 
 pub use rustc::ty::Instance;
@@ -89,10 +88,7 @@ fn fn_once_adapter_instance<'a, 'tcx>(
     let sig = substs.closure_sig(closure_did, tcx);
     let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
     assert_eq!(sig.inputs().len(), 1);
-    let substs = tcx.mk_substs([
-        Kind::from(self_ty),
-        sig.inputs()[0].into(),
-    ].iter().cloned());
+    let substs = tcx.mk_substs_trait(self_ty, &[sig.inputs()[0].into()]);
 
     debug!("fn_once_adapter_shim: self_ty={:?} sig={:?}", self_ty, sig);
     Instance { def, substs }
@@ -164,7 +160,7 @@ pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let trait_ref = ty::Binder::bind(ty::TraitRef {
         def_id: def_id,
-        substs: tcx.mk_substs_trait(source_ty, &[target_ty])
+        substs: tcx.mk_substs_trait(source_ty, &[target_ty.into()])
     });
 
     match tcx.codegen_fulfill_obligation( (ty::ParamEnv::reveal_all(), trait_ref)) {
diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs
index 2d2663bc7c3..8375a5fb334 100644
--- a/src/librustc_mir/shim.rs
+++ b/src/librustc_mir/shim.rs
@@ -13,7 +13,7 @@ use rustc::hir::def_id::DefId;
 use rustc::infer;
 use rustc::mir::*;
 use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind};
-use rustc::ty::subst::{Kind, Subst, Substs};
+use rustc::ty::subst::{Subst, Substs};
 use rustc::ty::maps::Providers;
 
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -170,7 +170,7 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     let substs = if let Some(ty) = ty {
-        tcx.mk_substs(iter::once(Kind::from(ty)))
+        tcx.intern_substs(&[ty.into()])
     } else {
         Substs::identity_for_item(tcx, def_id)
     };
@@ -430,7 +430,7 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> {
         let substs = Substs::for_item(tcx, self.def_id, |param, _| {
             match param.kind {
                 GenericParamDefKind::Lifetime => tcx.types.re_erased.into(),
-                GenericParamDefKind::Type(_) => ty.into(),
+                GenericParamDefKind::Type {..} => ty.into(),
             }
         });
 
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index 5da40d04b33..c9727f55d20 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -861,8 +861,10 @@ impl MirPass for StateTransform {
         // Compute GeneratorState<yield_ty, return_ty>
         let state_did = tcx.lang_items().gen_state().unwrap();
         let state_adt_ref = tcx.adt_def(state_did);
-        let state_substs = tcx.mk_substs([yield_ty.into(),
-            mir.return_ty().into()].iter());
+        let state_substs = tcx.intern_substs(&[
+            yield_ty.into(),
+            mir.return_ty().into(),
+        ]);
         let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
 
         // We rename RETURN_PLACE which has type mir.return_ty to new_ret_local
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 9fc04dc7d24..f70a5ef57fe 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -14,12 +14,12 @@ use rustc::mir::*;
 use rustc::middle::lang_items;
 use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::subst::{Kind, Substs};
+use rustc::ty::subst::Substs;
 use rustc::ty::util::IntTypeExt;
 use rustc_data_structures::indexed_vec::Idx;
 use util::patch::MirPatch;
 
-use std::{iter, u32};
+use std::u32;
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
 pub enum DropFlagState {
@@ -520,7 +520,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
         let drop_trait = tcx.lang_items().drop_trait().unwrap();
         let drop_fn = tcx.associated_items(drop_trait).next().unwrap();
         let ty = self.place_ty(self.place);
-        let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
+        let substs = tcx.mk_substs_trait(ty, &[]);
 
         let ref_ty = tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut {
             ty,
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 6e9b03cd2a9..2e887e3d8f0 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -401,8 +401,8 @@ impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> {
     fn generics(&mut self) -> &mut Self {
         for param in &self.ev.tcx.generics_of(self.item_def_id).params {
             match param.kind {
-                GenericParamDefKind::Type(ty) => {
-                    if ty.has_default {
+                GenericParamDefKind::Type { has_default, .. } => {
+                    if has_default {
                         self.ev.tcx.type_of(param.def_id).visit_with(self);
                     }
                 }
@@ -1342,8 +1342,8 @@ impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
     fn generics(&mut self) -> &mut Self {
         for param in &self.tcx.generics_of(self.item_def_id).params {
             match param.kind {
-                GenericParamDefKind::Type(ty) => {
-                    if ty.has_default {
+                GenericParamDefKind::Type { has_default, .. } => {
+                    if has_default {
                         self.tcx.type_of(param.def_id).visit_with(self);
                     }
                 }
diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs
index b6a086f609d..6e4c4a3ade3 100644
--- a/src/librustc_traits/lowering.rs
+++ b/src/librustc_traits/lowering.rs
@@ -220,7 +220,7 @@ fn program_clauses_for_trait<'a, 'tcx>(
     // `Implemented(Self: Trait<P1..Pn>) :- FromEnv(Self: Trait<P1..Pn>)`
     let implemented_from_env = ProgramClause {
         goal: impl_trait,
-        hypotheses: tcx.mk_goals(iter::once(from_env)),
+        hypotheses: tcx.intern_goals(&[from_env]),
     };
     let clauses = iter::once(Clause::ForAll(ty::Binder::dummy(implemented_from_env)));
 
@@ -256,7 +256,7 @@ fn implied_bound_from_trait<'a, 'tcx>(
     // `FromEnv(WC) :- FromEnv(Self: Trait<P1..Pn>)`
     Clause::ForAll(where_clause.lower().map_bound(|goal| ProgramClause {
         goal: goal.into_from_env_goal(),
-        hypotheses: tcx.mk_goals(iter::once(Goal::from(impl_trait))),
+        hypotheses: tcx.intern_goals(&[Goal::from(impl_trait)]),
     }))
 }
 
@@ -290,7 +290,7 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId
                 .map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
         ),
     };
-    tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
+    tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
 }
 
 pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
@@ -344,7 +344,7 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>(
                 .map(|wc| Goal::from_poly_domain_goal(wc, tcx)),
         ),
     };
-    tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause))))
+    tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))])
 }
 
 pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index e6ccbd61bd5..f2fe8b1d891 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -18,9 +18,9 @@ use hir::def::Def;
 use hir::def_id::DefId;
 use middle::resolve_lifetime as rl;
 use namespace::Namespace;
-use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs};
+use rustc::ty::subst::{Subst, Substs};
 use rustc::traits;
-use rustc::ty::{self, RegionKind, Ty, TyCtxt, ToPredicate, TypeFoldable};
+use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::GenericParamDefKind;
 use rustc::ty::wf::object_region_bounds;
 use rustc_target::spec::abi;
@@ -224,9 +224,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                 GenericParamDefKind::Lifetime => {
                     lt_accepted += 1;
                 }
-                GenericParamDefKind::Type(ty) => {
+                GenericParamDefKind::Type { has_default, .. } => {
                     ty_params.accepted += 1;
-                    if !ty.has_default {
+                    if !has_default {
                         ty_params.required += 1;
                     }
                 }
@@ -251,8 +251,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
 
         let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
         let default_needs_object_self = |param: &ty::GenericParamDef| {
-            if let GenericParamDefKind::Type(ty) = param.kind {
-                if is_object && ty.has_default {
+            if let GenericParamDefKind::Type { has_default, .. } = param.kind {
+                if is_object && has_default {
                     if tcx.at(span).type_of(param.def_id).has_self_ty() {
                         // There is no suitable inference default for a type parameter
                         // that references self, in an object type.
@@ -275,7 +275,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                         tcx.types.re_static.into()
                     }
                 }
-                GenericParamDefKind::Type(ty) => {
+                GenericParamDefKind::Type { has_default, .. } => {
                     let i = param.index as usize;
 
                     // Handle Self first, so we can adjust the index to match the AST.
@@ -294,7 +294,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                         } else {
                             self.ty_infer(span).into()
                         }
-                    } else if ty.has_default {
+                    } else if has_default {
                         // No type parameter provided, but a default exists.
 
                         // If we are converting an object type, then the
@@ -1152,32 +1152,29 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         let tcx = self.tcx();
         let generics = tcx.generics_of(def_id);
 
-        // Fill in the substs of the parent generics
         debug!("impl_trait_ty_to_ty: generics={:?}", generics);
-        let mut substs = Vec::with_capacity(generics.count());
-        if let Some(parent_id) = generics.parent {
-            let parent_generics = tcx.generics_of(parent_id);
-            Substs::fill_item(&mut substs, tcx, parent_generics, &mut |param, _| {
-                tcx.mk_param_from_def(param)
-            });
-
-            // Replace all lifetimes with 'static
-            for subst in &mut substs {
-                if let UnpackedKind::Lifetime(_) = subst.unpack() {
-                    *subst = Kind::from(&RegionKind::ReStatic);
+        let substs = Substs::for_item(tcx, def_id, |param, _| {
+            if let Some(i) = (param.index as usize).checked_sub(generics.parent_count) {
+                // Our own parameters are the resolved lifetimes.
+                match param.kind {
+                    GenericParamDefKind::Lifetime => {
+                        self.ast_region_to_region(&lifetimes[i], None).into()
+                    }
+                    _ => bug!()
+                }
+            } else {
+                // Replace all parent lifetimes with 'static.
+                match param.kind {
+                    GenericParamDefKind::Lifetime => {
+                        tcx.types.re_static.into()
+                    }
+                    _ => tcx.mk_param_from_def(param)
                 }
             }
-            debug!("impl_trait_ty_to_ty: substs from parent = {:?}", substs);
-        }
-        assert_eq!(substs.len(), generics.parent_count);
-
-        // Fill in our own generics with the resolved lifetimes
-        assert_eq!(lifetimes.len(), generics.params.len());
-        substs.extend(lifetimes.iter().map(|lt| Kind::from(self.ast_region_to_region(lt, None))));
-
+        });
         debug!("impl_trait_ty_to_ty: final substs = {:?}", substs);
 
-        tcx.mk_anon(def_id, tcx.intern_substs(&substs))
+        tcx.mk_anon(def_id, substs)
     }
 
     pub fn ty_of_arg(&self,
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index c2ec6475b9c..a7cdcae9c07 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -109,7 +109,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 GenericParamDefKind::Lifetime => {
                     span_bug!(expr.span, "closure has region param")
                 }
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type {..} => {
                     self.infcx
                         .next_ty_var(TypeVariableOrigin::ClosureSynthetic(expr.span)).into()
                 }
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 324af7b6270..5b3484dcccb 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -547,7 +547,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
                                                          coerce_unsized_did,
                                                          0,
                                                          coerce_source,
-                                                         &[coerce_target]));
+                                                         &[coerce_target.into()]));
 
         let mut has_unsized_tuple_coercion = false;
 
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index ba950f90d0a..f386b7e07c1 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -730,13 +730,13 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let trait_m_generics = tcx.generics_of(trait_m.def_id);
     let impl_m_type_params = impl_m_generics.params.iter().filter_map(|param| {
         match param.kind {
-            GenericParamDefKind::Type(ty) => Some((param.def_id, ty.synthetic)),
+            GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
             GenericParamDefKind::Lifetime => None,
         }
     });
     let trait_m_type_params = trait_m_generics.params.iter().filter_map(|param| {
         match param.kind {
-            GenericParamDefKind::Type(ty) => Some((param.def_id, ty.synthetic)),
+            GenericParamDefKind::Type { synthetic, .. } => Some((param.def_id, synthetic)),
             GenericParamDefKind::Lifetime => None,
         }
     });
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index aa3a166d065..7d9f2e094e1 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -331,7 +331,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
                                 self.fcx, lifetime, Some(param)).into();
                         }
                     }
-                    GenericParamDefKind::Type(_) => {
+                    GenericParamDefKind::Type {..} => {
                         if let Some(ast_ty) = provided.as_ref().and_then(|p| {
                             p.types.get(i - parent_substs.len() - own_counts.lifetimes)
                         }) {
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 15a8efd5885..8ffb6e99fc0 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -257,7 +257,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let substs = Substs::for_item(self.tcx, trait_def_id, |param, _| {
             match param.kind {
                 GenericParamDefKind::Lifetime => {}
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type {..} => {
                     if param.index == 0 {
                         return self_ty.into();
                     } else if let Some(ref input_types) = opt_input_types {
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 6b860dbe8fe..6cdfb0bccc9 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -1399,7 +1399,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
                             // `impl_self_ty()` for an explanation.
                             self.tcx.types.re_erased.into()
                         }
-                        GenericParamDefKind::Type(_) => self.var_for_def(self.span, param),
+                        GenericParamDefKind::Type {..} => self.var_for_def(self.span, param),
                     }
                 }
             });
@@ -1416,7 +1416,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
         Substs::for_item(self.tcx, def_id, |param, _| {
             match param.kind {
                 GenericParamDefKind::Lifetime => self.tcx.types.re_erased.into(),
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type {..} => {
                     self.next_ty_var(TypeVariableOrigin::SubstitutionPlaceholder(
                         self.tcx.def_span(def_id))).into()
                 }
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index 2dc7c7fe71a..8a575c14787 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -56,8 +56,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
                 self.autoderef(span, ty).any(|(ty, _)| {
                     self.probe(|_| {
-                        let fn_once_substs = tcx.mk_substs_trait(ty,
-                            &[self.next_ty_var(TypeVariableOrigin::MiscVariable(span))]);
+                        let fn_once_substs = tcx.mk_substs_trait(ty, &[
+                            self.next_ty_var(TypeVariableOrigin::MiscVariable(span)).into()
+                        ]);
                         let trait_ref = ty::TraitRef::new(fn_once, fn_once_substs);
                         let poly_trait_ref = trait_ref.to_poly_trait_ref();
                         let obligation =
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1088ec1b2ac..46dbccaa137 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -94,7 +94,7 @@ use rustc::infer::anon_types::AnonTypeDecl;
 use rustc::infer::type_variable::{TypeVariableOrigin};
 use rustc::middle::region;
 use rustc::mir::interpret::{GlobalId};
-use rustc::ty::subst::{Kind, UnpackedKind, Subst, Substs};
+use rustc::ty::subst::{UnpackedKind, Subst, Substs};
 use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
 use rustc::ty::{self, Ty, TyCtxt, GenericParamDefKind, Visibility, ToPredicate};
 use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability};
@@ -116,7 +116,6 @@ use std::collections::hash_map::Entry;
 use std::cmp;
 use std::fmt::Display;
 use std::mem::replace;
-use std::iter;
 use std::ops::{self, Deref};
 use rustc_target::spec::abi::Abi;
 use syntax::ast;
@@ -1114,7 +1113,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
             if id == fn_id {
                 match entry_type {
                     config::EntryMain => {
-                        let substs = fcx.tcx.mk_substs(iter::once(Kind::from(declared_ret_ty)));
+                        let substs = fcx.tcx.mk_substs_trait(declared_ret_ty, &[]);
                         let trait_ref = ty::TraitRef::new(term_id, substs);
                         let return_ty_span = decl.output.span();
                         let cause = traits::ObligationCause::new(
@@ -4752,10 +4751,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             let mut i = param.index as usize;
 
             let segment = if i < fn_start {
-                if let GenericParamDefKind::Type(_) = param.kind {
+                if let GenericParamDefKind::Type {..} = param.kind {
                     // Handle Self first, so we can adjust the index to match the AST.
                     if has_self && i == 0 {
-                        return opt_self_ty.map(|ty| Kind::from(ty)).unwrap_or_else(|| {
+                        return opt_self_ty.map(|ty| ty.into()).unwrap_or_else(|| {
                             self.var_for_def(span, param)
                         });
                     }
@@ -4779,7 +4778,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         self.re_infer(span, Some(param)).unwrap().into()
                     }
                 }
-                GenericParamDefKind::Type(_) => {
+                GenericParamDefKind::Type {..} => {
                     let (types, infer_types) = segment.map_or((&[][..], true), |(s, _)| {
                         (s.parameters.as_ref().map_or(&[][..], |p| &p.types[..]), s.infer_types)
                     });
@@ -4790,7 +4789,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     }
 
                     let has_default = match param.kind {
-                        GenericParamDefKind::Type(ty) => ty.has_default,
+                        GenericParamDefKind::Type { has_default, .. } => has_default,
                         _ => unreachable!()
                     };
 
@@ -4926,9 +4925,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         GenericParamDefKind::Lifetime => {
                             lt_accepted += 1;
                         }
-                        GenericParamDefKind::Type(ty) => {
+                        GenericParamDefKind::Type { has_default, .. } => {
                             ty_params.accepted += 1;
-                            if !ty.has_default {
+                            if !has_default {
                                 ty_params.required += 1;
                             }
                         }
@@ -5025,12 +5024,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         let segment = segment.map(|(path_segment, generics)| {
             let explicit = !path_segment.infer_types;
             let impl_trait = generics.params.iter().any(|param| {
-                if let ty::GenericParamDefKind::Type(ty) = param.kind {
-                    if let Some(hir::SyntheticTyParamKind::ImplTrait) = ty.synthetic {
-                        return true;
-                    }
+                match param.kind {
+                    ty::GenericParamDefKind::Type {
+                        synthetic: Some(hir::SyntheticTyParamKind::ImplTrait), ..
+                    } => true,
+                    _ => false,
                 }
-                false
             });
 
             if explicit && impl_trait {
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 0fc8c9cc316..4b4b982b1be 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -377,8 +377,8 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
     let generics = tcx.generics_of(def_id);
     let is_our_default = |def: &ty::GenericParamDef| {
         match def.kind {
-            GenericParamDefKind::Type(ty) => {
-                ty.has_default && def.index >= generics.parent_count as u32
+            GenericParamDefKind::Type { has_default, .. } => {
+                has_default && def.index >= generics.parent_count as u32
             }
             _ => unreachable!()
         }
@@ -389,7 +389,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
     // struct Foo<T = Vec<[u32]>> { .. }
     // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold.
     for param in &generics.params {
-        if let GenericParamDefKind::Type(_) = param.kind {
+        if let GenericParamDefKind::Type {..} = param.kind {
             if is_our_default(&param) {
                 let ty = fcx.tcx.type_of(param.def_id);
                 // ignore dependent defaults -- that is, where the default of one type
@@ -417,7 +417,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
                 // All regions are identity.
                 fcx.tcx.mk_param_from_def(param)
             }
-            GenericParamDefKind::Type(_) => {
+            GenericParamDefKind::Type {..} => {
                 // If the param has a default,
                 if is_our_default(param) {
                     let default_ty = fcx.tcx.type_of(param.def_id);
@@ -668,7 +668,7 @@ fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
                      .flat_map(|param| {
                          match param.kind {
                              GenericParamDefKind::Lifetime => None,
-                             GenericParamDefKind::Type(_) => Some((param.name, param.def_id)),
+                             GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
                          }
                      })
                      .collect();
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index 735ebbfcb3d..528f81a5612 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -387,7 +387,7 @@ pub fn coerce_unsized_info<'a, 'gcx>(gcx: TyCtxt<'a, 'gcx, 'gcx>,
                                                     trait_def_id,
                                                     0,
                                                     source,
-                                                    &[target]);
+                                                    &[target.into()]);
         fulfill_cx.register_predicate_obligation(&infcx, predicate);
 
         // Check that all transitive obligations are satisfied.
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 4d691de2037..d0d147b8e85 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -845,11 +845,11 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         name: keywords::SelfType.name().as_interned_str(),
                         def_id: tcx.hir.local_def_id(param_id),
                         pure_wrt_drop: false,
-                        kind: ty::GenericParamDefKind::Type(ty::TypeParamDef {
+                        kind: ty::GenericParamDefKind::Type {
                             has_default: false,
                             object_lifetime_default: rl::Set1::Empty,
                             synthetic: None,
-                        }),
+                        },
                     });
 
                     allow_defaults = true;
@@ -925,12 +925,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             name: p.name.as_interned_str(),
             def_id: tcx.hir.local_def_id(p.id),
             pure_wrt_drop: p.pure_wrt_drop,
-            kind: ty::GenericParamDefKind::Type(ty::TypeParamDef {
+            kind: ty::GenericParamDefKind::Type {
                 has_default: p.default.is_some(),
                 object_lifetime_default:
                     object_lifetime_defaults.as_ref().map_or(rl::Set1::Empty, |o| o[i]),
                 synthetic: p.synthetic,
-            }),
+            },
         }
     }));
 
@@ -950,11 +950,11 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 name: Symbol::intern(arg).as_interned_str(),
                 def_id,
                 pure_wrt_drop: false,
-                kind: ty::GenericParamDefKind::Type(ty::TypeParamDef {
+                kind: ty::GenericParamDefKind::Type {
                     has_default: false,
                     object_lifetime_default: rl::Set1::Empty,
                     synthetic: None,
-                }),
+                },
             });
         }
 
@@ -965,11 +965,11 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     name: Symbol::intern("<upvar>").as_interned_str(),
                     def_id,
                     pure_wrt_drop: false,
-                    kind: ty::GenericParamDefKind::Type(ty::TypeParamDef {
+                    kind: ty::GenericParamDefKind::Type {
                         has_default: false,
                         object_lifetime_default: rl::Set1::Empty,
                         synthetic: None,
-                    }),
+                    },
                 }
             }));
         });
diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs
index 80dde814c66..7b7cb254979 100644
--- a/src/librustc_typeck/impl_wf_check.rs
+++ b/src/librustc_typeck/impl_wf_check.rs
@@ -116,7 +116,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     for param in &impl_generics.params {
         match param.kind {
             // Disallow ANY unconstrained type parameters.
-            ty::GenericParamDefKind::Type(_) => {
+            ty::GenericParamDefKind::Type {..} => {
                 let param_ty = ty::ParamTy::for_def(param);
                 if !input_parameters.contains(&ctp::Parameter::from(param_ty)) {
                     report_unused_parameter(tcx,
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 73a7e0e690f..da749fca2a9 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -263,7 +263,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                         name,
                     });
                 }
-                ty::GenericParamDefKind::Type(_) => {
+                ty::GenericParamDefKind::Type {..} => {
                     types.push(P(self.ty_param_to_ty(param.clone())));
                 }
             }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ae53b9ded4e..d4c1ba63a8c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1340,7 +1340,7 @@ impl<'tcx> Clean<TyParam> for ty::GenericParamDef {
     fn clean(&self, cx: &DocContext) -> TyParam {
         cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
         let has_default = match self.kind {
-            ty::GenericParamDefKind::Type(ty) => ty.has_default,
+            ty::GenericParamDefKind::Type { has_default, .. } => has_default,
             _ => panic!("tried to convert a non-type GenericParamDef as a type")
         };
         TyParam {
@@ -1827,7 +1827,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
         // predicates field (see rustc_typeck::collect::ty_generics), so remove
         // them.
         let stripped_typarams = gens.params.iter().filter_map(|param| {
-            if let ty::GenericParamDefKind::Type(_) = param.kind {
+            if let ty::GenericParamDefKind::Type {..} = param.kind {
                 if param.name == keywords::SelfType.name().as_str() {
                     assert_eq!(param.index, 0);
                     None