]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/ty/sty.rs
generate GeneratorSubsts from SubstsRef
[rust.git] / src / librustc / ty / sty.rs
index da66fdf5b1b1b724f9aba3042eeb37d224648b00..ff20996df56ff52e59b597275d1053f9082125d1 100644 (file)
@@ -8,12 +8,12 @@
 use crate::mir::interpret::ConstValue;
 use crate::middle::region;
 use polonius_engine::Atom;
-use rustc_data_structures::indexed_vec::Idx;
+use rustc_index::vec::Idx;
 use rustc_macros::HashStable;
-use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, Kind, UnpackedKind};
+use crate::ty::subst::{InternalSubsts, Subst, SubstsRef, GenericArg, GenericArgKind};
 use crate::ty::{self, AdtDef, Discr, DefIdTree, TypeFlags, Ty, TyCtxt, TypeFoldable};
 use crate::ty::{List, TyS, ParamEnvAnd, ParamEnv};
-use crate::ty::layout::VariantIdx;
+use crate::ty::layout::{Size, Integer, IntegerExt, VariantIdx};
 use crate::util::captures::Captures;
 use crate::mir::interpret::{Scalar, GlobalId};
 
@@ -24,6 +24,7 @@
 use std::ops::Range;
 use rustc_target::spec::abi;
 use syntax::ast::{self, Ident};
+use syntax::attr::{SignedInt, UnsignedInt};
 use syntax::symbol::{kw, InternedString};
 
 use self::InferTy::*;
@@ -86,6 +87,7 @@ pub fn assert_bound_var(&self) -> BoundVar {
 /// AST structure in `libsyntax/ast.rs` as well.
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
          RustcEncodable, RustcDecodable, HashStable, Debug)]
+#[rustc_diagnostic_item = "TyKind"]
 pub enum TyKind<'tcx> {
     /// The primitive boolean type. Written as `bool`.
     Bool,
@@ -157,11 +159,11 @@ pub enum TyKind<'tcx> {
 
     /// The anonymous type of a closure. Used to represent the type of
     /// `|a| a`.
-    Closure(DefId, ClosureSubsts<'tcx>),
+    Closure(DefId, SubstsRef<'tcx>),
 
     /// The anonymous type of a generator. Used to represent the type of
     /// `|a| yield a`.
-    Generator(DefId, GeneratorSubsts<'tcx>, hir::GeneratorMovability),
+    Generator(DefId, SubstsRef<'tcx>, hir::GeneratorMovability),
 
     /// A type representin the types stored inside a generator.
     /// This should only appear in GeneratorInteriors.
@@ -303,8 +305,8 @@ pub enum TyKind<'tcx> {
 /// type parameters is similar, but the role of CK and CS are
 /// different. CK represents the "yield type" and CS represents the
 /// "return type" of the generator.
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash,
-         Debug, RustcEncodable, RustcDecodable, HashStable)]
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug,
+         RustcEncodable, RustcDecodable, HashStable)]
 pub struct ClosureSubsts<'tcx> {
     /// Lifetime and type parameters from the enclosing function,
     /// concatenated with the types of the upvars.
@@ -319,7 +321,7 @@ pub struct ClosureSubsts<'tcx> {
 struct SplitClosureSubsts<'tcx> {
     closure_kind_ty: Ty<'tcx>,
     closure_sig_ty: Ty<'tcx>,
-    upvar_kinds: &'tcx [Kind<'tcx>],
+    upvar_kinds: &'tcx [GenericArg<'tcx>],
 }
 
 impl<'tcx> ClosureSubsts<'tcx> {
@@ -344,7 +346,7 @@ pub fn upvar_tys(
     ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let SplitClosureSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
         upvar_kinds.iter().map(|t| {
-            if let UnpackedKind::Type(ty) = t.unpack() {
+            if let GenericArgKind::Type(ty) = t.unpack() {
                 ty
             } else {
                 bug!("upvar should be type")
@@ -355,7 +357,7 @@ pub fn upvar_tys(
     /// Returns the closure kind for this closure; may return a type
     /// variable during inference. To get the closure kind during
     /// inference, use `infcx.closure_kind(def_id, substs)`.
-    pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
+    pub fn kind_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).closure_kind_ty
     }
 
@@ -363,7 +365,7 @@ pub fn closure_kind_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
     /// closure; may contain type variables during inference. To get
     /// the closure signature during inference, use
     /// `infcx.fn_sig(def_id)`.
-    pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
+    pub fn sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
         self.split(def_id, tcx).closure_sig_ty
     }
 
@@ -372,7 +374,7 @@ pub fn closure_sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
     /// there are no type variables.
     ///
     /// If you have an inference context, use `infcx.closure_kind()`.
-    pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::ClosureKind {
+    pub fn kind(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::ClosureKind {
         self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
     }
 
@@ -381,11 +383,11 @@ pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::ClosureKind {
     /// there are no type variables.
     ///
     /// If you have an inference context, use `infcx.closure_sig()`.
-    pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
-        let ty = self.closure_sig_ty(def_id, tcx);
-        match ty.sty {
+    pub fn sig(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
+        let ty = self.sig_ty(def_id, tcx);
+        match ty.kind {
             ty::FnPtr(sig) => sig,
-            _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty),
+            _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.kind),
         }
     }
 }
@@ -401,7 +403,7 @@ struct SplitGeneratorSubsts<'tcx> {
     yield_ty: Ty<'tcx>,
     return_ty: Ty<'tcx>,
     witness: Ty<'tcx>,
-    upvar_kinds: &'tcx [Kind<'tcx>],
+    upvar_kinds: &'tcx [GenericArg<'tcx>],
 }
 
 impl<'tcx> GeneratorSubsts<'tcx> {
@@ -433,7 +435,7 @@ pub fn upvar_tys(
     ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let SplitGeneratorSubsts { upvar_kinds, .. } = self.split(def_id, tcx);
         upvar_kinds.iter().map(|t| {
-            if let UnpackedKind::Type(ty) = t.unpack() {
+            if let GenericArgKind::Type(ty) = t.unpack() {
                 ty
             } else {
                 bug!("upvar should be type")
@@ -567,7 +569,7 @@ pub fn prefix_tys(self, def_id: DefId, tcx: TyCtxt<'tcx>) -> impl Iterator<Item
 
 #[derive(Debug, Copy, Clone)]
 pub enum UpvarSubsts<'tcx> {
-    Closure(ClosureSubsts<'tcx>),
+    Closure(SubstsRef<'tcx>),
     Generator(GeneratorSubsts<'tcx>),
 }
 
@@ -576,14 +578,14 @@ impl<'tcx> UpvarSubsts<'tcx> {
     pub fn upvar_tys(
         self,
         def_id: DefId,
-        tcx: TyCtxt<'_>,
+        tcx: TyCtxt<'tcx>,
     ) -> impl Iterator<Item = Ty<'tcx>> + 'tcx {
         let upvar_kinds = match self {
-            UpvarSubsts::Closure(substs) => substs.split(def_id, tcx).upvar_kinds,
+            UpvarSubsts::Closure(substs) => substs.as_closure().split(def_id, tcx).upvar_kinds,
             UpvarSubsts::Generator(substs) => substs.split(def_id, tcx).upvar_kinds,
         };
         upvar_kinds.iter().map(|t| {
-            if let UnpackedKind::Type(ty) = t.unpack() {
+            if let GenericArgKind::Type(ty) = t.unpack() {
                 ty
             } else {
                 bug!("upvar should be type")
@@ -643,7 +645,7 @@ pub fn with_self_ty(&self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> ty::Predicat
 impl<'tcx> rustc_serialize::UseSpecializedDecodable for &'tcx List<ExistentialPredicate<'tcx>> {}
 
 impl<'tcx> List<ExistentialPredicate<'tcx>> {
-    /// Returns the "principal def id" of this set of existential predicates.
+    /// Returns the "principal `DefId`" of this set of existential predicates.
     ///
     /// A Rust trait object type consists (in addition to a lifetime bound)
     /// of a set of trait bounds, which are separated into any number
@@ -1051,7 +1053,7 @@ pub fn return_ty(&self) -> ty::Binder<Ty<'tcx>> {
     }
 }
 
-/// Signature of a function type, which I have arbitrarily
+/// Signature of a function type, which we have arbitrarily
 /// decided to use to refer to the input/output types.
 ///
 /// - `inputs`: is the list of arguments and their modes.
@@ -1075,7 +1077,8 @@ pub fn output(&self) -> Ty<'tcx> {
         self.inputs_and_output[self.inputs_and_output.len() - 1]
     }
 
-    // Create a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible method
+    // Creates a minimal `FnSig` to be used when encountering a `TyKind::Error` in a fallible
+    // method.
     fn fake() -> FnSig<'tcx> {
         FnSig {
             inputs_and_output: List::empty(),
@@ -1117,7 +1120,6 @@ pub fn abi(&self) -> abi::Abi {
 
 pub type CanonicalPolyFnSig<'tcx> = Canonical<'tcx, Binder<FnSig<'tcx>>>;
 
-
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord,
          Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct ParamTy {
@@ -1164,7 +1166,7 @@ pub fn to_const(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
     }
 }
 
-newtype_index! {
+rustc_index::newtype_index! {
     /// A [De Bruijn index][dbi] is a standard means of representing
     /// regions (and perhaps later types) in a higher-ranked setting. In
     /// particular, imagine a type like this:
@@ -1348,7 +1350,7 @@ pub struct FloatVid {
     pub index: u32,
 }
 
-newtype_index! {
+rustc_index::newtype_index! {
     pub struct RegionVid {
         DEBUG_FORMAT = custom,
     }
@@ -1375,7 +1377,7 @@ pub enum InferTy {
     FreshFloatTy(u32),
 }
 
-newtype_index! {
+rustc_index::newtype_index! {
     pub struct BoundVar { .. }
 }
 
@@ -1677,7 +1679,7 @@ pub fn free_region_binding_scope(&self, tcx: TyCtxt<'_>) -> DefId {
 impl<'tcx> TyS<'tcx> {
     #[inline]
     pub fn is_unit(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Tuple(ref tys) => tys.is_empty(),
             _ => false,
         }
@@ -1685,7 +1687,7 @@ pub fn is_unit(&self) -> bool {
 
     #[inline]
     pub fn is_never(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Never => true,
             _ => false,
         }
@@ -1700,7 +1702,7 @@ pub fn is_never(&self) -> bool {
     pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
         // FIXME(varkor): we can make this less conversative by substituting concrete
         // type arguments.
-        match self.sty {
+        match self.kind {
             ty::Never => true,
             ty::Adt(def, _) if def.is_union() => {
                 // For now, `union`s are never considered uninhabited.
@@ -1740,7 +1742,7 @@ pub fn conservative_is_privately_uninhabited(&self, tcx: TyCtxt<'tcx>) -> bool {
 
     #[inline]
     pub fn is_primitive(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Bool | Char | Int(_) | Uint(_) | Float(_) => true,
             _ => false,
         }
@@ -1748,7 +1750,7 @@ pub fn is_primitive(&self) -> bool {
 
     #[inline]
     pub fn is_ty_var(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Infer(TyVar(_)) => true,
             _ => false,
         }
@@ -1756,7 +1758,7 @@ pub fn is_ty_var(&self) -> bool {
 
     #[inline]
     pub fn is_ty_infer(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Infer(_) => true,
             _ => false,
         }
@@ -1764,7 +1766,7 @@ pub fn is_ty_infer(&self) -> bool {
 
     #[inline]
     pub fn is_phantom_data(&self) -> bool {
-        if let Adt(def, _) = self.sty {
+        if let Adt(def, _) = self.kind {
             def.is_phantom_data()
         } else {
             false
@@ -1772,11 +1774,11 @@ pub fn is_phantom_data(&self) -> bool {
     }
 
     #[inline]
-    pub fn is_bool(&self) -> bool { self.sty == Bool }
+    pub fn is_bool(&self) -> bool { self.kind == Bool }
 
     #[inline]
     pub fn is_param(&self, index: u32) -> bool {
-        match self.sty {
+        match self.kind {
             ty::Param(ref data) => data.index == index,
             _ => false,
         }
@@ -1784,8 +1786,8 @@ pub fn is_param(&self, index: u32) -> bool {
 
     #[inline]
     pub fn is_slice(&self) -> bool {
-        match self.sty {
-            RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => match ty.sty {
+        match self.kind {
+            RawPtr(TypeAndMut { ty, .. }) | Ref(_, ty, _) => match ty.kind {
                 Slice(_) | Str => true,
                 _ => false,
             },
@@ -1795,14 +1797,14 @@ pub fn is_slice(&self) -> bool {
 
     #[inline]
     pub fn is_simd(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Adt(def, _) => def.repr.simd(),
             _ => false,
         }
     }
 
     pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match self.sty {
+        match self.kind {
             Array(ty, _) | Slice(ty) => ty,
             Str => tcx.mk_mach_uint(ast::UintTy::U8),
             _ => bug!("sequence_element_type called on non-sequence value: {}", self),
@@ -1810,7 +1812,7 @@ pub fn sequence_element_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
     }
 
     pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
-        match self.sty {
+        match self.kind {
             Adt(def, substs) => {
                 def.non_enum_variant().fields[0].ty(tcx, substs)
             }
@@ -1819,7 +1821,7 @@ pub fn simd_type(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
     }
 
     pub fn simd_size(&self, _cx: TyCtxt<'_>) -> usize {
-        match self.sty {
+        match self.kind {
             Adt(def, _) => def.non_enum_variant().fields.len(),
             _ => bug!("simd_size called on invalid type")
         }
@@ -1827,7 +1829,7 @@ pub fn simd_size(&self, _cx: TyCtxt<'_>) -> usize {
 
     #[inline]
     pub fn is_region_ptr(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Ref(..) => true,
             _ => false,
         }
@@ -1835,7 +1837,7 @@ pub fn is_region_ptr(&self) -> bool {
 
     #[inline]
     pub fn is_mutable_ptr(&self) -> bool {
-        match self.sty {
+        match self.kind {
             RawPtr(TypeAndMut { mutbl: hir::Mutability::MutMutable, .. }) |
             Ref(_, _, hir::Mutability::MutMutable) => true,
             _ => false
@@ -1844,7 +1846,7 @@ pub fn is_mutable_ptr(&self) -> bool {
 
     #[inline]
     pub fn is_unsafe_ptr(&self) -> bool {
-        match self.sty {
+        match self.kind {
             RawPtr(_) => return true,
             _ => return false,
         }
@@ -1859,7 +1861,7 @@ pub fn is_any_ptr(&self) -> bool {
     /// Returns `true` if this type is an `Arc<T>`.
     #[inline]
     pub fn is_arc(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Adt(def, _) => def.is_arc(),
             _ => false,
         }
@@ -1868,7 +1870,7 @@ pub fn is_arc(&self) -> bool {
     /// Returns `true` if this type is an `Rc<T>`.
     #[inline]
     pub fn is_rc(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Adt(def, _) => def.is_rc(),
             _ => false,
         }
@@ -1876,7 +1878,7 @@ pub fn is_rc(&self) -> bool {
 
     #[inline]
     pub fn is_box(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Adt(def, _) => def.is_box(),
             _ => false,
         }
@@ -1884,7 +1886,7 @@ pub fn is_box(&self) -> bool {
 
     /// panics if called on any type other than `Box<T>`
     pub fn boxed_ty(&self) -> Ty<'tcx> {
-        match self.sty {
+        match self.kind {
             Adt(def, substs) if def.is_box() => substs.type_at(0),
             _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
         }
@@ -1895,7 +1897,7 @@ pub fn boxed_ty(&self) -> Ty<'tcx> {
     /// contents are abstract to rustc.)
     #[inline]
     pub fn is_scalar(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Bool | Char | Int(_) | Float(_) | Uint(_) |
             Infer(IntVar(_)) | Infer(FloatVar(_)) |
             FnDef(..) | FnPtr(_) | RawPtr(_) => true,
@@ -1906,7 +1908,7 @@ pub fn is_scalar(&self) -> bool {
     /// Returns `true` if this type is a floating point type.
     #[inline]
     pub fn is_floating_point(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Float(_) |
             Infer(FloatVar(_)) => true,
             _ => false,
@@ -1915,7 +1917,7 @@ pub fn is_floating_point(&self) -> bool {
 
     #[inline]
     pub fn is_trait(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Dynamic(..) => true,
             _ => false,
         }
@@ -1923,7 +1925,7 @@ pub fn is_trait(&self) -> bool {
 
     #[inline]
     pub fn is_enum(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Adt(adt_def, _) => {
                 adt_def.is_enum()
             }
@@ -1933,7 +1935,7 @@ pub fn is_enum(&self) -> bool {
 
     #[inline]
     pub fn is_closure(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Closure(..) => true,
             _ => false,
         }
@@ -1941,7 +1943,7 @@ pub fn is_closure(&self) -> bool {
 
     #[inline]
     pub fn is_generator(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Generator(..) => true,
             _ => false,
         }
@@ -1949,7 +1951,7 @@ pub fn is_generator(&self) -> bool {
 
     #[inline]
     pub fn is_integral(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Infer(IntVar(_)) | Int(_) | Uint(_) => true,
             _ => false
         }
@@ -1957,7 +1959,7 @@ pub fn is_integral(&self) -> bool {
 
     #[inline]
     pub fn is_fresh_ty(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Infer(FreshTy(_)) => true,
             _ => false,
         }
@@ -1965,7 +1967,7 @@ pub fn is_fresh_ty(&self) -> bool {
 
     #[inline]
     pub fn is_fresh(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Infer(FreshTy(_)) => true,
             Infer(FreshIntTy(_)) => true,
             Infer(FreshFloatTy(_)) => true,
@@ -1975,7 +1977,7 @@ pub fn is_fresh(&self) -> bool {
 
     #[inline]
     pub fn is_char(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Char => true,
             _ => false,
         }
@@ -1988,7 +1990,7 @@ pub fn is_numeric(&self) -> bool {
 
     #[inline]
     pub fn is_signed(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Int(_) => true,
             _ => false,
         }
@@ -1996,7 +1998,7 @@ pub fn is_signed(&self) -> bool {
 
     #[inline]
     pub fn is_ptr_sized_integral(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => true,
             _ => false,
         }
@@ -2004,7 +2006,7 @@ pub fn is_ptr_sized_integral(&self) -> bool {
 
     #[inline]
     pub fn is_machine(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Int(..) | Uint(..) | Float(..) => true,
             _ => false,
         }
@@ -2012,7 +2014,7 @@ pub fn is_machine(&self) -> bool {
 
     #[inline]
     pub fn has_concrete_skeleton(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Param(_) | Infer(_) | Error => false,
             _ => true,
         }
@@ -2023,7 +2025,7 @@ pub fn has_concrete_skeleton(&self) -> bool {
     /// The parameter `explicit` indicates if this is an *explicit* dereference.
     /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
     pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
-        match self.sty {
+        match self.kind {
             Adt(def, _) if def.is_box() => {
                 Some(TypeAndMut {
                     ty: self.boxed_ty(),
@@ -2038,14 +2040,14 @@ pub fn builtin_deref(&self, explicit: bool) -> Option<TypeAndMut<'tcx>> {
 
     /// Returns the type of `ty[i]`.
     pub fn builtin_index(&self) -> Option<Ty<'tcx>> {
-        match self.sty {
+        match self.kind {
             Array(ty, _) | Slice(ty) => Some(ty),
             _ => None,
         }
     }
 
     pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
-        match self.sty {
+        match self.kind {
             FnDef(def_id, substs) => {
                 tcx.fn_sig(def_id).subst(tcx, substs)
             }
@@ -2062,7 +2064,7 @@ pub fn fn_sig(&self, tcx: TyCtxt<'tcx>) -> PolyFnSig<'tcx> {
 
     #[inline]
     pub fn is_fn(&self) -> bool {
-        match self.sty {
+        match self.kind {
             FnDef(..) | FnPtr(_) => true,
             _ => false,
         }
@@ -2070,7 +2072,7 @@ pub fn is_fn(&self) -> bool {
 
     #[inline]
     pub fn is_fn_ptr(&self) -> bool {
-        match self.sty {
+        match self.kind {
             FnPtr(_) => true,
             _ => false,
         }
@@ -2078,7 +2080,7 @@ pub fn is_fn_ptr(&self) -> bool {
 
     #[inline]
     pub fn is_impl_trait(&self) -> bool {
-        match self.sty {
+        match self.kind {
             Opaque(..) => true,
             _ => false,
         }
@@ -2086,7 +2088,7 @@ pub fn is_impl_trait(&self) -> bool {
 
     #[inline]
     pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
-        match self.sty {
+        match self.kind {
             Adt(adt, _) => Some(adt),
             _ => None,
         }
@@ -2095,7 +2097,7 @@ pub fn ty_adt_def(&self) -> Option<&'tcx AdtDef> {
     /// Iterates over tuple fields.
     /// Panics when called on anything but a tuple.
     pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> {
-        match self.sty {
+        match self.kind {
             Tuple(substs) => substs.iter().map(|field| field.expect_ty()),
             _ => bug!("tuple_fields called on non-tuple"),
         }
@@ -2105,9 +2107,10 @@ pub fn tuple_fields(&self) -> impl DoubleEndedIterator<Item=Ty<'tcx>> {
     /// FIXME This requires the optimized MIR in the case of generators.
     #[inline]
     pub fn variant_range(&self, tcx: TyCtxt<'tcx>) -> Option<Range<VariantIdx>> {
-        match self.sty {
+        match self.kind {
             TyKind::Adt(adt, _) => Some(adt.variant_range()),
-            TyKind::Generator(def_id, substs, _) => Some(substs.variant_range(def_id, tcx)),
+            TyKind::Generator(def_id, substs, _) =>
+                Some(substs.assert_generator().variant_range(def_id, tcx)),
             _ => None,
         }
     }
@@ -2121,10 +2124,10 @@ pub fn discriminant_for_variant(
         tcx: TyCtxt<'tcx>,
         variant_index: VariantIdx,
     ) -> Option<Discr<'tcx>> {
-        match self.sty {
+        match self.kind {
             TyKind::Adt(adt, _) => Some(adt.discriminant_for_variant(tcx, variant_index)),
             TyKind::Generator(def_id, substs, _) =>
-                Some(substs.discriminant_for_variant(def_id, tcx, variant_index)),
+                Some(substs.as_generator().discriminant_for_variant(def_id, tcx, variant_index)),
             _ => None,
         }
     }
@@ -2133,7 +2136,7 @@ pub fn discriminant_for_variant(
     /// types reachable from this type via `walk_tys`). This ignores late-bound
     /// regions binders.
     pub fn push_regions(&self, out: &mut SmallVec<[ty::Region<'tcx>; 4]>) {
-        match self.sty {
+        match self.kind {
             Ref(region, _, _) => {
                 out.push(region);
             }
@@ -2146,8 +2149,8 @@ pub fn discriminant_for_variant(
             Adt(_, substs) | Opaque(_, substs) => {
                 out.extend(substs.regions())
             }
-            Closure(_, ClosureSubsts { ref substs }) |
-            Generator(_, GeneratorSubsts { ref substs }, _) => {
+            Closure(_, ref substs ) |
+            Generator(_, ref substs, _) => {
                 out.extend(substs.regions())
             }
             Projection(ref data) | UnnormalizedProjection(ref data) => {
@@ -2189,7 +2192,7 @@ pub fn discriminant_for_variant(
     /// inferred. Once upvar inference (in `src/librustc_typeck/check/upvar.rs`)
     /// is complete, that type variable will be unified.
     pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
-        match self.sty {
+        match self.kind {
             Int(int_ty) => match int_ty {
                 ast::IntTy::I8 => Some(ty::ClosureKind::Fn),
                 ast::IntTy::I16 => Some(ty::ClosureKind::FnMut),
@@ -2210,7 +2213,7 @@ pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
     /// Returning true means the type is known to be sized. Returning
     /// `false` means nothing -- could be sized, might not be.
     pub fn is_trivially_sized(&self, tcx: TyCtxt<'tcx>) -> bool {
-        match self.sty {
+        match self.kind {
             ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) |
             ty::Uint(_) | ty::Int(_) | ty::Bool | ty::Float(_) |
             ty::FnDef(..) | ty::FnPtr(_) | ty::RawPtr(..) |
@@ -2297,8 +2300,21 @@ pub fn try_eval_bits(
         ty: Ty<'tcx>,
     ) -> Option<u128> {
         assert_eq!(self.ty, ty);
+        // This is purely an optimization -- layout_of is a pretty expensive operation,
+        // but if we can determine the size without calling it, we don't need all that complexity
+        // (hashing, caching, etc.). As such, try to skip it.
+        let size = match ty.kind {
+            ty::Bool => Size::from_bytes(1),
+            ty::Char => Size::from_bytes(4),
+            ty::Int(ity) => {
+                Integer::from_attr(&tcx, SignedInt(ity)).size()
+            }
+            ty::Uint(uty) => {
+                Integer::from_attr(&tcx, UnsignedInt(uty)).size()
+            }
+            _ => tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size,
+        };
         // if `ty` does not depend on generic parameters, use an empty param_env
-        let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size;
         self.eval(tcx, param_env).val.try_to_bits(size)
     }