about summary refs log tree commit diff
path: root/src/librustc/ty
diff options
context:
space:
mode:
authorOliver Scherer <github35764891676564198441@oli-obk.de>2019-03-14 10:19:31 +0100
committerOliver Scherer <github35764891676564198441@oli-obk.de>2019-03-16 21:04:10 +0100
commit5cd28066214a4a255bac6655c20bf05cb95730fd (patch)
treea05eb07e841948afde869d2008b0aab68f55d24a /src/librustc/ty
parent2c8bbf50db0ef90a33f986ba8fc2e1fe129197ff (diff)
downloadrust-5cd28066214a4a255bac6655c20bf05cb95730fd.tar.gz
rust-5cd28066214a4a255bac6655c20bf05cb95730fd.zip
Revert the `LazyConst` PR
Diffstat (limited to 'src/librustc/ty')
-rw-r--r--src/librustc/ty/codec.rs12
-rw-r--r--src/librustc/ty/context.rs43
-rw-r--r--src/librustc/ty/error.rs9
-rw-r--r--src/librustc/ty/flags.rs38
-rw-r--r--src/librustc/ty/fold.rs16
-rw-r--r--src/librustc/ty/inhabitedness/mod.rs19
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc/ty/print/pretty.rs35
-rw-r--r--src/librustc/ty/relate.rs10
-rw-r--r--src/librustc/ty/structural_impls.rs86
-rw-r--r--src/librustc/ty/sty.rs79
-rw-r--r--src/librustc/ty/subst.rs29
-rw-r--r--src/librustc/ty/util.rs4
-rw-r--r--src/librustc/ty/walk.rs4
-rw-r--r--src/librustc/ty/wf.rs5
15 files changed, 130 insertions, 261 deletions
diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs
index 3ab744ebaeb..e7474345c00 100644
--- a/src/librustc/ty/codec.rs
+++ b/src/librustc/ty/codec.rs
@@ -247,12 +247,12 @@ pub fn decode_canonical_var_infos<'a, 'tcx, D>(decoder: &mut D)
 }
 
 #[inline]
-pub fn decode_lazy_const<'a, 'tcx, D>(decoder: &mut D)
-                                 -> Result<&'tcx ty::LazyConst<'tcx>, D::Error>
+pub fn decode_const<'a, 'tcx, D>(decoder: &mut D)
+                                 -> Result<&'tcx ty::Const<'tcx>, D::Error>
     where D: TyDecoder<'a, 'tcx>,
           'tcx: 'a,
 {
-    Ok(decoder.tcx().mk_lazy_const(Decodable::decode(decoder)?))
+    Ok(decoder.tcx().mk_const(Decodable::decode(decoder)?))
 }
 
 #[inline]
@@ -389,10 +389,10 @@ macro_rules! implement_ty_decoder {
                 }
             }
 
-            impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::LazyConst<'tcx>>
+            impl<$($typaram),*> SpecializedDecoder<&'tcx $crate::ty::Const<'tcx>>
             for $DecoderName<$($typaram),*> {
-                fn specialized_decode(&mut self) -> Result<&'tcx ty::LazyConst<'tcx>, Self::Error> {
-                    decode_lazy_const(self)
+                fn specialized_decode(&mut self) -> Result<&'tcx ty::Const<'tcx>, Self::Error> {
+                    decode_const(self)
                 }
             }
 
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 1942f98abff..6de0a39c91b 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -28,7 +28,7 @@ use crate::traits;
 use crate::traits::{Clause, Clauses, GoalKind, Goal, Goals};
 use crate::ty::{self, DefIdTree, Ty, TypeAndMut};
 use crate::ty::{TyS, TyKind, List};
-use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const, LazyConst};
+use crate::ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const};
 use crate::ty::{PolyFnSig, InferTy, ParamTy, ProjectionTy, ExistentialPredicate, Predicate};
 use crate::ty::RegionKind;
 use crate::ty::{TyVar, TyVid, IntVar, IntVid, FloatVar, FloatVid, ConstVid};
@@ -126,7 +126,7 @@ pub struct CtxtInterners<'tcx> {
     goal: InternedSet<'tcx, GoalKind<'tcx>>,
     goal_list: InternedSet<'tcx, List<Goal<'tcx>>>,
     projs: InternedSet<'tcx, List<ProjectionKind<'tcx>>>,
-    lazy_const: InternedSet<'tcx, LazyConst<'tcx>>,
+    const_: InternedSet<'tcx, Const<'tcx>>,
 }
 
 impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
@@ -144,7 +144,7 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> {
             goal: Default::default(),
             goal_list: Default::default(),
             projs: Default::default(),
-            lazy_const: Default::default(),
+            const_: Default::default(),
         }
     }
 
@@ -874,14 +874,11 @@ impl CanonicalUserType<'gcx> {
                             _ => false,
                         },
 
-                        UnpackedKind::Const(ct) => match ct {
-                            ty::LazyConst::Evaluated(ty::Const {
-                                val: ConstValue::Infer(InferConst::Canonical(debruijn, b)),
-                                ..
-                            }) => {
+                        UnpackedKind::Const(ct) => match ct.val {
+                            ConstValue::Infer(InferConst::Canonical(debruijn, b)) => {
                                 // We only allow a `ty::INNERMOST` index in substitutions.
-                                assert_eq!(*debruijn, ty::INNERMOST);
-                                cvar == *b
+                                assert_eq!(debruijn, ty::INNERMOST);
+                                cvar == b
                             }
                             _ => false,
                         },
@@ -1788,7 +1785,7 @@ macro_rules! nop_list_lift {
 nop_lift!{Ty<'a> => Ty<'tcx>}
 nop_lift!{Region<'a> => Region<'tcx>}
 nop_lift!{Goal<'a> => Goal<'tcx>}
-nop_lift!{&'a LazyConst<'a> => &'tcx LazyConst<'tcx>}
+nop_lift!{&'a Const<'a> => &'tcx Const<'tcx>}
 
 nop_list_lift!{Goal<'a> => Goal<'tcx>}
 nop_list_lift!{Clause<'a> => Clause<'tcx>}
@@ -2274,12 +2271,6 @@ impl<'tcx: 'lcx, 'lcx> Borrow<GoalKind<'lcx>> for Interned<'tcx, GoalKind<'tcx>>
     }
 }
 
-impl<'tcx: 'lcx, 'lcx> Borrow<LazyConst<'lcx>> for Interned<'tcx, LazyConst<'tcx>> {
-    fn borrow<'a>(&'a self) -> &'a LazyConst<'lcx> {
-        &self.0
-    }
-}
-
 impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]>
     for Interned<'tcx, List<ExistentialPredicate<'tcx>>> {
     fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] {
@@ -2387,7 +2378,7 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool {
 direct_interners!('tcx,
     region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind,
     goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx>,
-    lazy_const: mk_lazy_const(|c: &LazyConst<'_>| keep_local(&c)) -> LazyConst<'tcx>
+    const_: mk_const(|c: &Const<'_>| keep_local(&c)) -> Const<'tcx>
 );
 
 macro_rules! slice_interners {
@@ -2575,8 +2566,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
     #[inline]
     pub fn mk_array(self, ty: Ty<'tcx>, n: u64) -> Ty<'tcx> {
-        self.mk_ty(Array(ty, self.mk_lazy_const(
-            ty::LazyConst::Evaluated(ty::Const::from_usize(self.global_tcx(), n))
+        self.mk_ty(Array(ty, self.mk_const(
+            ty::Const::from_usize(self.global_tcx(), n)
         )))
     }
 
@@ -2670,11 +2661,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     #[inline]
-    pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx LazyConst<'tcx> {
-        self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
+    pub fn mk_const_var(self, v: ConstVid<'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
+        self.mk_const(ty::Const {
             val: ConstValue::Infer(InferConst::Var(v)),
             ty,
-        }))
+        })
     }
 
     #[inline]
@@ -2705,11 +2696,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         index: u32,
         name: InternedString,
         ty: Ty<'tcx>
-    ) -> &'tcx LazyConst<'tcx> {
-        self.mk_lazy_const(LazyConst::Evaluated(ty::Const {
+    ) -> &'tcx Const<'tcx> {
+        self.mk_const(ty::Const {
             val: ConstValue::Param(ParamConst { index, name }),
             ty,
-        }))
+        })
     }
 
     #[inline]
diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs
index fa3c76a817a..74d0a29bcff 100644
--- a/src/librustc/ty/error.rs
+++ b/src/librustc/ty/error.rs
@@ -176,12 +176,9 @@ impl<'a, 'gcx, 'lcx, 'tcx> ty::TyS<'tcx> {
 
             ty::Adt(def, _) => format!("{} `{}`", def.descr(), tcx.def_path_str(def.did)).into(),
             ty::Foreign(def_id) => format!("extern type `{}`", tcx.def_path_str(def_id)).into(),
-            ty::Array(_, n) => match n {
-                ty::LazyConst::Evaluated(n) => match n.assert_usize(tcx) {
-                    Some(n) => format!("array of {} elements", n).into(),
-                    None => "array".into(),
-                },
-                ty::LazyConst::Unevaluated(..) => "array".into(),
+            ty::Array(_, n) => match n.assert_usize(tcx) {
+                Some(n) => format!("array of {} elements", n).into(),
+                None => "array".into(),
             }
             ty::Slice(_) => "slice".into(),
             ty::RawPtr(_) => "*-ptr".into(),
diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs
index 64ceb9729ed..7aed2a4288c 100644
--- a/src/librustc/ty/flags.rs
+++ b/src/librustc/ty/flags.rs
@@ -24,6 +24,12 @@ impl FlagComputation {
         result
     }
 
+    pub fn for_const(c: &ty::Const<'_>) -> TypeFlags {
+        let mut result = FlagComputation::new();
+        result.add_const(c);
+        result.flags
+    }
+
     fn add_flags(&mut self, flags: TypeFlags) {
         self.flags = self.flags | (flags & TypeFlags::NOMINAL_FLAGS);
     }
@@ -173,10 +179,7 @@ impl FlagComputation {
 
             &ty::Array(tt, len) => {
                 self.add_ty(tt);
-                if let ty::LazyConst::Unevaluated(_, substs) = len {
-                    self.add_flags(TypeFlags::HAS_PROJECTION);
-                    self.add_substs(substs);
-                }
+                self.add_const(len);
             }
 
             &ty::Slice(tt) => {
@@ -233,19 +236,26 @@ impl FlagComputation {
         }
     }
 
-    fn add_const(&mut self, c: &ty::LazyConst<'_>) {
-        match c {
-            ty::LazyConst::Unevaluated(_, substs) => self.add_substs(substs),
-            // Only done to add the binder for the type. The type flags are
-            // included in `Const::type_flags`.
-            ty::LazyConst::Evaluated(ty::Const { ty, val }) => {
-                self.add_ty(ty);
-                if let ConstValue::Infer(InferConst::Canonical(debruijn, _)) = val {
-                    self.add_binder(*debruijn)
+    fn add_const(&mut self, c: &ty::Const<'_>) {
+        self.add_ty(c.ty);
+        match c.val {
+            ConstValue::Unevaluated(_, substs) => {
+                self.add_substs(substs);
+                self.add_flags(TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_PROJECTION);
+            },
+            ConstValue::Infer(infer) => {
+                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_CT_INFER);
+                match infer {
+                    InferConst::Fresh(_) => {}
+                    InferConst::Canonical(debruijn, _) => self.add_binder(debruijn),
+                    InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
                 }
             }
+            ConstValue::Param(_) => {
+                self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES | TypeFlags::HAS_PARAMS);
+            }
+            _ => {},
         }
-        self.add_flags(c.type_flags());
     }
 
     fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs
index 7f77d037bb6..321e55270c6 100644
--- a/src/librustc/ty/fold.rs
+++ b/src/librustc/ty/fold.rs
@@ -32,7 +32,7 @@
 //! looking for, and does not need to visit anything else.
 
 use crate::hir::def_id::DefId;
-use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags};
+use crate::ty::{self, Binder, Ty, TyCtxt, TypeFlags, flags::FlagComputation};
 
 use std::collections::BTreeMap;
 use std::fmt;
@@ -167,7 +167,7 @@ pub trait TypeFolder<'gcx: 'tcx, 'tcx> : Sized {
         r.super_fold_with(self)
     }
 
-    fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+    fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
         c.super_fold_with(self)
     }
 }
@@ -185,7 +185,7 @@ pub trait TypeVisitor<'tcx> : Sized {
         r.super_visit_with(self)
     }
 
-    fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
+    fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
         c.super_visit_with(self)
     }
 }
@@ -842,14 +842,10 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
         flags.intersects(self.flags)
     }
 
-    fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool {
-        let flags = c.type_flags();
+    fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool {
+        let flags = FlagComputation::for_const(c);
         debug!("HasTypeFlagsVisitor: c={:?} c.flags={:?} self.flags={:?}", c, flags, self.flags);
-        if flags.intersects(self.flags) {
-            true
-        } else {
-            c.super_visit_with(self)
-        }
+        flags.intersects(self.flags) || c.super_visit_with(self)
     }
 }
 
diff --git a/src/librustc/ty/inhabitedness/mod.rs b/src/librustc/ty/inhabitedness/mod.rs
index 33ec9c874f9..d732f3ff040 100644
--- a/src/librustc/ty/inhabitedness/mod.rs
+++ b/src/librustc/ty/inhabitedness/mod.rs
@@ -1,6 +1,6 @@
 use crate::ty::context::TyCtxt;
 use crate::ty::{AdtDef, VariantDef, FieldDef, Ty, TyS};
-use crate::ty::{self, DefId, SubstsRef};
+use crate::ty::{DefId, SubstsRef};
 use crate::ty::{AdtKind, Visibility};
 use crate::ty::TyKind::*;
 
@@ -212,17 +212,12 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
                 }))
             }
 
-            Array(ty, len) => {
-                match len {
-                    ty::LazyConst::Unevaluated(..) => DefIdForest::empty(),
-                    ty::LazyConst::Evaluated(len) => match len.assert_usize(tcx) {
-                        // If the array is definitely non-empty, it's uninhabited if
-                        // the type of its elements is uninhabited.
-                        Some(n) if n != 0 => ty.uninhabited_from(tcx),
-                        _ => DefIdForest::empty()
-                    },
-                }
-            }
+            Array(ty, len) => match len.assert_usize(tcx) {
+                // If the array is definitely non-empty, it's uninhabited if
+                // the type of its elements is uninhabited.
+                Some(n) if n != 0 => ty.uninhabited_from(tcx),
+                _ => DefIdForest::empty()
+            },
 
             // References to uninitialised memory is valid for any type, including
             // uninhabited types, in unsafe code, so we treat all references as
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 882e2dc62b1..298af1d00c9 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -59,7 +59,7 @@ pub use self::sty::{InferTy, ParamTy, ParamConst, InferConst, ProjectionTy, Exis
 pub use self::sty::{ClosureSubsts, GeneratorSubsts, UpvarSubsts, TypeAndMut};
 pub use self::sty::{TraitRef, TyKind, PolyTraitRef};
 pub use self::sty::{ExistentialTraitRef, PolyExistentialTraitRef};
-pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const, LazyConst};
+pub use self::sty::{ExistentialProjection, PolyExistentialProjection, Const};
 pub use self::sty::{BoundRegion, EarlyBoundRegion, FreeRegion, Region};
 pub use self::sty::RegionKind;
 pub use self::sty::{TyVid, IntVid, FloatVid, ConstVid, RegionVid};
diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs
index fa57e0b9674..7701a10d8ee 100644
--- a/src/librustc/ty/print/pretty.rs
+++ b/src/librustc/ty/print/pretty.rs
@@ -660,18 +660,12 @@ pub trait PrettyPrinter<'gcx: 'tcx, 'tcx>:
             },
             ty::Array(ty, sz) => {
                 p!(write("["), print(ty), write("; "));
-                match sz {
-                    ty::LazyConst::Unevaluated(_def_id, _substs) => {
-                        p!(write("_"));
-                    }
-                    ty::LazyConst::Evaluated(c) => {
-                        match c.val {
-                            ConstValue::Infer(..) => p!(write("_")),
-                            ConstValue::Param(ParamConst { name, .. }) =>
-                                p!(write("{}", name)),
-                            _ => p!(write("{}", c.unwrap_usize(self.tcx()))),
-                        }
-                    }
+                match sz.val {
+                    ConstValue::Unevaluated(..) |
+                    ConstValue::Infer(..) => p!(write("_")),
+                    ConstValue::Param(ParamConst { name, .. }) =>
+                        p!(write("{}", name)),
+                    _ => p!(write("{}", sz.unwrap_usize(self.tcx()))),
                 }
                 p!(write("]"))
             }
@@ -1533,26 +1527,15 @@ define_print_and_forward_display! {
         p!(print_def_path(self.def_id, self.substs));
     }
 
-    ConstValue<'tcx> {
-        match self {
+    &'tcx ty::Const<'tcx> {
+        match self.val {
+            ConstValue::Unevaluated(..) |
             ConstValue::Infer(..) => p!(write("_")),
             ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
             _ => p!(write("{:?}", self)),
         }
     }
 
-    ty::Const<'tcx> {
-        p!(write("{} : {}", self.val, self.ty))
-    }
-
-    &'tcx ty::LazyConst<'tcx> {
-        match self {
-            // FIXME(const_generics) this should print at least the type.
-            ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
-            ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
-        }
-    }
-
     ty::ParamTy {
         p!(write("{}", self.name))
     }
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index b245d903799..810bd10c8f4 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
 use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
 use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
 use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::GlobalId;
+use crate::mir::interpret::{GlobalId, ConstValue};
 use crate::util::common::ErrorReported;
 use syntax_pos::DUMMY_SP;
 use std::rc::Rc;
@@ -466,9 +466,9 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
         (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) =>
         {
             let t = relation.relate(&a_t, &b_t)?;
-            let to_u64 = |x: ty::LazyConst<'tcx>| -> Result<u64, ErrorReported> {
-                match x {
-                    ty::LazyConst::Unevaluated(def_id, substs) => {
+            let to_u64 = |x: ty::Const<'tcx>| -> Result<u64, ErrorReported> {
+                match x.val {
+                    ConstValue::Unevaluated(def_id, substs) => {
                         // FIXME(eddyb) get the right param_env.
                         let param_env = ty::ParamEnv::empty();
                         if let Some(substs) = tcx.lift_to_global(&substs) {
@@ -494,7 +494,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
                             "array length could not be evaluated");
                         Err(ErrorReported)
                     }
-                    ty::LazyConst::Evaluated(c) => c.assert_usize(tcx).ok_or_else(|| {
+                    _ => x.assert_usize(tcx).ok_or_else(|| {
                         tcx.sess.delay_span_bug(DUMMY_SP,
                             "array length could not be evaluated");
                         ErrorReported
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index ecfb034e4f2..cbdda732692 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -6,7 +6,7 @@
 use crate::hir::def::Namespace;
 use crate::mir::ProjectionKind;
 use crate::mir::interpret::ConstValue;
-use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst};
+use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid};
 use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
 use crate::ty::print::{FmtPrinter, Printer};
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -794,34 +794,6 @@ BraceStructLiftImpl! {
     }
 }
 
-BraceStructLiftImpl! {
-    impl<'a, 'tcx> Lift<'tcx> for ty::Const<'a> {
-        type Lifted = ty::Const<'tcx>;
-        val, ty
-    }
-}
-
-impl<'a, 'tcx> Lift<'tcx> for ConstValue<'a> {
-    type Lifted = ConstValue<'tcx>;
-    fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
-        match *self {
-            ConstValue::Param(param) => Some(ConstValue::Param(param)),
-            ConstValue::Infer(infer) => {
-                Some(ConstValue::Infer(match infer {
-                    InferConst::Var(vid) => InferConst::Var(vid.lift_to_tcx(tcx)?),
-                    InferConst::Fresh(i) => InferConst::Fresh(i),
-                    InferConst::Canonical(debrujin, var) => InferConst::Canonical(debrujin, var),
-                }))
-            }
-            ConstValue::Scalar(x) => Some(ConstValue::Scalar(x)),
-            ConstValue::Slice(x, y) => Some(ConstValue::Slice(x, y)),
-            ConstValue::ByRef(ptr, alloc) => Some(ConstValue::ByRef(
-                ptr, alloc.lift_to_tcx(tcx)?,
-            )),
-        }
-    }
-}
-
 impl<'a, 'tcx> Lift<'tcx> for ConstVid<'a> {
     type Lifted = ConstVid<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, _: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
@@ -1362,15 +1334,14 @@ EnumTypeFoldableImpl! {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::Const<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        let new = match self {
-            ty::LazyConst::Evaluated(v) => ty::LazyConst::Evaluated(v.fold_with(folder)),
-            ty::LazyConst::Unevaluated(def_id, substs) => {
-                ty::LazyConst::Unevaluated(*def_id, substs.fold_with(folder))
-            }
-        };
-        folder.tcx().mk_lazy_const(new)
+        let ty = self.ty.fold_with(folder);
+        let val = self.val.fold_with(folder);
+        folder.tcx().mk_const(ty::Const {
+            ty,
+            val
+        })
     }
 
     fn fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
@@ -1378,10 +1349,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> {
     }
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        match *self {
-            ty::LazyConst::Evaluated(c) => c.visit_with(visitor),
-            ty::LazyConst::Unevaluated(_, substs) => substs.visit_with(visitor),
-        }
+        self.ty.visit_with(visitor) || self.val.visit_with(visitor)
     }
 
     fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
@@ -1389,27 +1357,29 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::LazyConst<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::Const<'tcx> {
+impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        let ty = self.ty.fold_with(folder);
-        let val = self.val.fold_with(folder);
-        ty::Const {
-            ty,
-            val
+        match *self {
+            ConstValue::ByRef(ptr, alloc) => ConstValue::ByRef(ptr, alloc),
+            // FIXME(const_generics): implement TypeFoldable for InferConst
+            ConstValue::Infer(ic) => ConstValue::Infer(ic),
+            ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)),
+            ConstValue::Scalar(a) => ConstValue::Scalar(a),
+            ConstValue::Slice(a, b) => ConstValue::Slice(a, b),
+            ConstValue::Unevaluated(did, substs)
+                => ConstValue::Unevaluated(did, substs.fold_with(folder)),
         }
     }
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.ty.visit_with(visitor) || self.val.visit_with(visitor)
-    }
-}
-
-impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self {
-        *self
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool {
-        false
+        match *self {
+            ConstValue::ByRef(..) => false,
+            // FIXME(const_generics): implement TypeFoldable for InferConst
+            ConstValue::Infer(_ic) => false,
+            ConstValue::Param(p) => p.visit_with(visitor),
+            ConstValue::Scalar(_) => false,
+            ConstValue::Slice(..) => false,
+            ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor),
+        }
     }
 }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 7b6a51c0184..df76e6127e8 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -118,7 +118,7 @@ pub enum TyKind<'tcx> {
     Str,
 
     /// An array with the given length. Written as `[T; n]`.
-    Array(Ty<'tcx>, &'tcx ty::LazyConst<'tcx>),
+    Array(Ty<'tcx>, &'tcx ty::Const<'tcx>),
 
     /// The pointee of an array slice. Written as `[T]`.
     Slice(Ty<'tcx>),
@@ -1089,7 +1089,7 @@ impl<'a, 'gcx, 'tcx> ParamConst {
         ParamConst::new(def.index, def.name)
     }
 
-    pub fn to_const(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx LazyConst<'tcx> {
+    pub fn to_const(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, ty: Ty<'tcx>) -> &'tcx Const<'tcx> {
         tcx.mk_const_param(self.index, self.name, ty)
     }
 }
@@ -2096,52 +2096,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable,
-         Eq, PartialEq, Ord, PartialOrd, HashStable)]
-/// Used in the HIR by using `Unevaluated` everywhere and later normalizing to `Evaluated` if the
-/// code is monomorphic enough for that.
-pub enum LazyConst<'tcx> {
-    Unevaluated(DefId, SubstsRef<'tcx>),
-    Evaluated(Const<'tcx>),
-}
-
-#[cfg(target_arch = "x86_64")]
-static_assert!(LAZY_CONST_SIZE: ::std::mem::size_of::<LazyConst<'static>>() == 56);
-
-impl<'tcx> LazyConst<'tcx> {
-    pub fn map_evaluated<R>(self, f: impl FnOnce(Const<'tcx>) -> Option<R>) -> Option<R> {
-        match self {
-            LazyConst::Evaluated(c) => f(c),
-            LazyConst::Unevaluated(..) => None,
-        }
-    }
-
-    pub fn assert_usize(self, tcx: TyCtxt<'_, '_, '_>) -> Option<u64> {
-        self.map_evaluated(|c| c.assert_usize(tcx))
-    }
-
-    #[inline]
-    pub fn unwrap_usize(&self, tcx: TyCtxt<'_, '_, '_>) -> u64 {
-        self.assert_usize(tcx).expect("expected `LazyConst` to contain a usize")
-    }
-
-    pub fn type_flags(&self) -> TypeFlags {
-        // FIXME(const_generics): incorporate substs flags.
-        let flags = match self {
-            LazyConst::Unevaluated(..) => {
-                TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_PROJECTION
-            }
-            LazyConst::Evaluated(c) => {
-                c.type_flags()
-            }
-        };
-
-        debug!("type_flags({:?}) = {:?}", self, flags);
-
-        flags
-    }
-}
-
 /// Typed constant value.
 #[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable,
          Eq, PartialEq, Ord, PartialOrd, HashStable)]
@@ -2256,36 +2210,9 @@ impl<'tcx> Const<'tcx> {
         self.assert_usize(tcx).unwrap_or_else(||
             bug!("expected constant usize, got {:#?}", self))
     }
-
-    pub fn type_flags(&self) -> TypeFlags {
-        let mut flags = self.ty.flags;
-
-        match self.val {
-            ConstValue::Param(_) => {
-                flags |= TypeFlags::HAS_FREE_LOCAL_NAMES;
-                flags |= TypeFlags::HAS_PARAMS;
-            }
-            ConstValue::Infer(infer) => {
-                flags |= TypeFlags::HAS_FREE_LOCAL_NAMES;
-                flags |= TypeFlags::HAS_CT_INFER;
-                match infer {
-                    InferConst::Fresh(_) |
-                    InferConst::Canonical(_, _) => {}
-                    InferConst::Var(_) => {
-                        flags |= TypeFlags::KEEP_IN_LOCAL_TCX;
-                    }
-                }
-            }
-            _ => {}
-        }
-
-        debug!("type_flags({:?}) = {:?}", self, flags);
-
-        flags
-    }
 }
 
-impl<'tcx> serialize::UseSpecializedDecodable for &'tcx LazyConst<'tcx> {}
+impl<'tcx> serialize::UseSpecializedDecodable for &'tcx Const<'tcx> {}
 
 /// An inference variable for a const, for use in const generics.
 #[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd,
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 84642865614..3ba2c4cbf6c 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -26,7 +26,7 @@ use std::num::NonZeroUsize;
 #[derive(Copy, Clone, PartialEq, Eq, Hash)]
 pub struct Kind<'tcx> {
     ptr: NonZeroUsize,
-    marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::LazyConst<'tcx>)>
+    marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, &'tcx ty::Const<'tcx>)>
 }
 
 const TAG_MASK: usize = 0b11;
@@ -38,7 +38,7 @@ const CONST_TAG: usize = 0b10;
 pub enum UnpackedKind<'tcx> {
     Lifetime(ty::Region<'tcx>),
     Type(Ty<'tcx>),
-    Const(&'tcx ty::LazyConst<'tcx>),
+    Const(&'tcx ty::Const<'tcx>),
 }
 
 impl<'tcx> UnpackedKind<'tcx> {
@@ -104,8 +104,8 @@ impl<'tcx> From<Ty<'tcx>> for Kind<'tcx> {
     }
 }
 
-impl<'tcx> From<&'tcx ty::LazyConst<'tcx>> for Kind<'tcx> {
-    fn from(c: &'tcx ty::LazyConst<'tcx>) -> Kind<'tcx> {
+impl<'tcx> From<&'tcx ty::Const<'tcx>> for Kind<'tcx> {
+    fn from(c: &'tcx ty::Const<'tcx>) -> Kind<'tcx> {
         UnpackedKind::Const(c).pack()
     }
 }
@@ -208,12 +208,12 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
                 }
 
                 ty::GenericParamDefKind::Const => {
-                    tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const {
+                    tcx.mk_const(ty::Const {
                         val: ConstValue::Infer(
                             InferConst::Canonical(ty::INNERMOST, ty::BoundVar::from(param.index))
                         ),
                         ty: tcx.type_of(def_id),
-                    })).into()
+                    }).into()
                 }
             }
         })
@@ -304,7 +304,7 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
     }
 
     #[inline]
-    pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::LazyConst<'tcx>> + 'a {
+    pub fn consts(&'a self) -> impl DoubleEndedIterator<Item = &'tcx ty::Const<'tcx>> + 'a {
         self.iter().filter_map(|k| {
             if let UnpackedKind::Const(ct) = k.unpack() {
                 Some(ct)
@@ -345,7 +345,7 @@ impl<'a, 'gcx, 'tcx> InternalSubsts<'tcx> {
     }
 
     #[inline]
-    pub fn const_at(&self, i: usize) -> &'tcx ty::LazyConst<'tcx> {
+    pub fn const_at(&self, i: usize) -> &'tcx ty::Const<'tcx> {
         if let UnpackedKind::Const(ct) = self[i].unpack() {
             ct
         } else {
@@ -522,16 +522,13 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for SubstFolder<'a, 'gcx, 'tcx> {
         return t1;
     }
 
-    fn fold_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> {
+    fn fold_const(&mut self, c: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
         if !c.needs_subst() {
             return c;
         }
 
-        if let ty::LazyConst::Evaluated(ty::Const {
-            val: ConstValue::Param(p),
-            ..
-        }) = c {
-            self.const_for_param(*p, c)
+        if let ConstValue::Param(p) = c.val {
+            self.const_for_param(p, c)
         } else {
             c.super_fold_with(self)
         }
@@ -564,8 +561,8 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
     fn const_for_param(
         &self,
         p: ParamConst,
-        source_cn: &'tcx ty::LazyConst<'tcx>
-    ) -> &'tcx ty::LazyConst<'tcx> {
+        source_cn: &'tcx ty::Const<'tcx>
+    ) -> &'tcx ty::Const<'tcx> {
         // Look up the const in the substitutions. It really should be in there.
         let opt_cn = self.substs.get(p.index as usize).map(|k| k.unpack());
         let cn = match opt_cn {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 65918a90821..4fb2bfb075c 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -497,10 +497,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                     }) => {
                         !impl_generics.type_param(pt, self).pure_wrt_drop
                     }
-                    UnpackedKind::Const(&ty::LazyConst::Evaluated(ty::Const {
+                    UnpackedKind::Const(&ty::Const {
                         val: ConstValue::Param(ref pc),
                         ..
-                    })) => {
+                    }) => {
                         !impl_generics.const_param(pc, self).pure_wrt_drop
                     }
                     UnpackedKind::Lifetime(_) |
diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs
index d9f309ae58e..fa1eadf34ac 100644
--- a/src/librustc/ty/walk.rs
+++ b/src/librustc/ty/walk.rs
@@ -3,6 +3,7 @@
 
 use crate::ty::{self, Ty};
 use smallvec::{self, SmallVec};
+use crate::mir::interpret::ConstValue;
 
 // The TypeWalker's stack is hot enough that it's worth going to some effort to
 // avoid heap allocations.
@@ -74,9 +75,10 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) {
         ty::Placeholder(..) | ty::Bound(..) | ty::Foreign(..) => {
         }
         ty::Array(ty, len) => {
-            if let ty::LazyConst::Unevaluated(_, substs) = len {
+            if let ConstValue::Unevaluated(_, substs) = len.val {
                 stack.extend(substs.types().rev());
             }
+            stack.push(len.ty);
             stack.push(ty);
         }
         ty::Slice(ty) => {
diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs
index fa35416cdd4..7bfda6a6557 100644
--- a/src/librustc/ty/wf.rs
+++ b/src/librustc/ty/wf.rs
@@ -7,6 +7,7 @@ use crate::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable};
 use std::iter::once;
 use syntax_pos::Span;
 use crate::middle::lang_items;
+use crate::mir::interpret::ConstValue;
 
 /// Returns the set of obligations needed to make `ty` well-formed.
 /// If `ty` contains unresolved inference variables, this may include
@@ -203,8 +204,8 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
 
     /// Pushes the obligations required for an array length to be WF
     /// into `self.out`.
-    fn compute_array_len(&mut self, constant: ty::LazyConst<'tcx>) {
-        if let ty::LazyConst::Unevaluated(def_id, substs) = constant {
+    fn compute_array_len(&mut self, constant: ty::Const<'tcx>) {
+        if let ConstValue::Unevaluated(def_id, substs) = constant.val {
             let obligations = self.nominal_obligations(def_id, substs);
             self.out.extend(obligations);