diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 9620ac95d86d1..7b47c02de1b54 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -1,7 +1,8 @@ use std::fmt; use rustc_macros::HashStable; -use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}}; +use crate::ty::{Ty, InferConst, ParamConst, layout::{HasDataLayout, Size}, subst::SubstsRef}; +use crate::hir::def_id::DefId; use super::{EvalResult, Pointer, PointerArithmetic, Allocation, AllocId, sign_extend, truncate}; @@ -42,6 +43,10 @@ pub enum ConstValue<'tcx> { /// An allocation together with a pointer into the allocation. /// Invariant: the pointer's `AllocId` resolves to the allocation. ByRef(Pointer, &'tcx Allocation), + + /// Used in the HIR by using `Unevaluated` everywhere and later normalizing to one of the other + /// variants when the code is monomorphic enough for that. + Unevaluated(DefId, SubstsRef<'tcx>), } #[cfg(target_arch = "x86_64")] @@ -54,6 +59,7 @@ impl<'tcx> ConstValue<'tcx> { ConstValue::Param(_) | ConstValue::Infer(_) | ConstValue::ByRef(..) | + ConstValue::Unevaluated(..) | ConstValue::Slice(..) => None, ConstValue::Scalar(val) => Some(val), } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 718b506d05113..9f2027e7d0563 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2179,8 +2179,8 @@ impl<'tcx> Operand<'tcx> { span, ty, user_ty: None, - literal: tcx.mk_lazy_const( - ty::LazyConst::Evaluated(ty::Const::zero_sized(ty)), + literal: tcx.mk_const( + ty::Const::zero_sized(ty), ), }) } @@ -2497,7 +2497,7 @@ pub struct Constant<'tcx> { /// Needed for NLL to impose user-given type constraints. pub user_ty: Option, - pub literal: &'tcx ty::LazyConst<'tcx>, + pub literal: &'tcx ty::Const<'tcx>, } /// A collection of projections into user types. @@ -2696,18 +2696,9 @@ newtype_index! { impl<'tcx> Debug for Constant<'tcx> { fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result { write!(fmt, "const ")?; - fmt_lazy_const_val(fmt, self.literal) + fmt_const_val(fmt, *self.literal) } } - -/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output. -pub fn fmt_lazy_const_val(f: &mut impl Write, const_val: &ty::LazyConst<'_>) -> fmt::Result { - match *const_val { - ty::LazyConst::Unevaluated(..) => write!(f, "{:?}", const_val), - ty::LazyConst::Evaluated(c) => fmt_const_val(f, c), - } -} - /// Write a `ConstValue` in a way closer to the original source code than the `Debug` output. pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Result { use crate::ty::TyKind::*; @@ -2760,7 +2751,7 @@ pub fn fmt_const_val(f: &mut impl Write, const_val: ty::Const<'_>) -> fmt::Resul } } // just raw dump everything else - write!(f, "{:?}:{}", value, ty) + write!(f, "{:?} : {}", value, ty) } fn def_path_str(def_id: DefId) -> String { diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 28e816f134365..8bc0075c47719 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -232,7 +232,7 @@ macro_rules! make_mir_visitor { } fn visit_const(&mut self, - constant: & $($mutability)? &'tcx ty::LazyConst<'tcx>, + constant: & $($mutability)? &'tcx ty::Const<'tcx>, _: Location) { self.super_const(constant); } @@ -886,7 +886,7 @@ macro_rules! make_mir_visitor { fn super_region(&mut self, _region: & $($mutability)? ty::Region<'tcx>) { } - fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::LazyConst<'tcx>) { + fn super_const(&mut self, _const: & $($mutability)? &'tcx ty::Const<'tcx>) { } fn super_substs(&mut self, _substs: & $($mutability)? SubstsRef<'tcx>) { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index ab6acc662131b..360e2323b647d 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -15,7 +15,7 @@ use super::util; use crate::hir::def_id::DefId; use crate::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime}; use crate::infer::type_variable::TypeVariableOrigin; -use crate::mir::interpret::{GlobalId}; +use crate::mir::interpret::{GlobalId, ConstValue}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use rustc_macros::HashStable; use syntax::ast::Ident; @@ -397,8 +397,8 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, } } - fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { - if let ty::LazyConst::Unevaluated(def_id, substs) = *constant { + fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + if let ConstValue::Unevaluated(def_id, substs) = constant.val { let tcx = self.selcx.tcx().global_tcx(); if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) { if substs.needs_infer() || substs.has_placeholders() { @@ -411,8 +411,9 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, }; if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { let substs = tcx.lift_to_global(&substs).unwrap(); + let evaluated = tcx.mk_const(evaluated); let evaluated = evaluated.subst(tcx, substs); - return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return evaluated; } } } else { @@ -424,7 +425,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, promoted: None }; if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { - return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return tcx.mk_const(evaluated); } } } diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index 8a30c18d6e5f7..9940249da8ba9 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -5,7 +5,7 @@ use crate::infer::at::At; use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; -use crate::mir::interpret::GlobalId; +use crate::mir::interpret::{GlobalId, ConstValue}; use crate::traits::project::Normalized; use crate::traits::{Obligation, ObligationCause, PredicateObligation, Reveal}; use crate::ty::fold::{TypeFoldable, TypeFolder}; @@ -188,8 +188,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx } } - fn fold_const(&mut self, constant: &'tcx ty::LazyConst<'tcx>) -> &'tcx ty::LazyConst<'tcx> { - if let ty::LazyConst::Unevaluated(def_id, substs) = *constant { + fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { + if let ConstValue::Unevaluated(def_id, substs) = constant.val { let tcx = self.infcx.tcx.global_tcx(); if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) { if substs.needs_infer() || substs.has_placeholders() { @@ -202,8 +202,9 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx }; if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { let substs = tcx.lift_to_global(&substs).unwrap(); + let evaluated = tcx.mk_const(evaluated); let evaluated = evaluated.subst(tcx, substs); - return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return evaluated; } } } else { @@ -215,7 +216,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx promoted: None, }; if let Ok(evaluated) = tcx.const_eval(param_env.and(cid)) { - return tcx.mk_lazy_const(ty::LazyConst::Evaluated(evaluated)); + return tcx.mk_const(evaluated); } } } diff --git a/src/librustc/ty/codec.rs b/src/librustc/ty/codec.rs index 3ab744ebaeb17..e7474345c0056 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 1942f98abff17..6de0a39c91b51 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>>, projs: InternedSet<'tcx, List>>, - 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> for Interned<'tcx, GoalKind<'tcx>> } } -impl<'tcx: 'lcx, 'lcx> Borrow> 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>> { 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 fa3c76a817a4f..74d0a29bcff00 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 64ceb9729ed15..7aed2a4288c8e 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 7f77d037bb6a1..321e55270c689 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 33ec9c874f9ef..d732f3ff04086 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 882e2dc62b1c3..298af1d00c9b7 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 fa57e0b96745a..7701a10d8eeee 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 b245d90379996..810bd10c8f4f7 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 { - match x { - ty::LazyConst::Unevaluated(def_id, substs) => { + let to_u64 = |x: ty::Const<'tcx>| -> Result { + 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 ecfb034e4f2fe..cbdda73269282 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 { - 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 { @@ -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>(&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>(&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>(&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>(&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 7b6a51c018459..df76e6127e842 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::>() == 56); - -impl<'tcx> LazyConst<'tcx> { - pub fn map_evaluated(self, f: impl FnOnce(Const<'tcx>) -> Option) -> Option { - match self { - LazyConst::Evaluated(c) => f(c), - LazyConst::Unevaluated(..) => None, - } - } - - pub fn assert_usize(self, tcx: TyCtxt<'_, '_, '_>) -> Option { - 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 8464286561469..3ba2c4cbf6c8c 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> 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> + 'a { + pub fn consts(&'a self) -> impl DoubleEndedIterator> + '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 65918a9082102..4fb2bfb075c8f 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 d9f309ae58e03..fa1eadf34ac89 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 fa35416cdd498..7bfda6a6557a3 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); diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 2bb68dc687ca9..a1d44b228a516 100644 --- a/src/librustc_codegen_ssa/mir/constant.rs +++ b/src/librustc_codegen_ssa/mir/constant.rs @@ -2,7 +2,6 @@ use rustc::mir::interpret::ErrorHandled; use rustc_mir::const_eval::const_field; use rustc::mir; use rustc_data_structures::indexed_vec::Idx; -use rustc::mir::interpret::GlobalId; use rustc::ty::{self, Ty}; use rustc::ty::layout; use syntax::source_map::Span; @@ -11,35 +10,27 @@ use crate::traits::*; use super::FunctionCx; impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { - fn fully_evaluate( + pub fn eval_mir_constant( &mut self, bx: &Bx, - constant: &'tcx ty::LazyConst<'tcx>, + constant: &mir::Constant<'tcx>, ) -> Result, ErrorHandled> { - match *constant { - ty::LazyConst::Unevaluated(def_id, ref substs) => { - let tcx = bx.tcx(); - let param_env = ty::ParamEnv::reveal_all(); - let instance = ty::Instance::resolve(tcx, param_env, def_id, substs).unwrap(); - let cid = GlobalId { + match constant.literal.val { + mir::interpret::ConstValue::Unevaluated(def_id, ref substs) => { + let substs = self.monomorphize(substs); + let instance = ty::Instance::resolve( + bx.tcx(), ty::ParamEnv::reveal_all(), def_id, substs, + ).unwrap(); + let cid = mir::interpret::GlobalId { instance, promoted: None, }; - tcx.const_eval(param_env.and(cid)) + bx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid)) }, - ty::LazyConst::Evaluated(constant) => Ok(constant), + _ => Ok(*self.monomorphize(&constant.literal)), } } - pub fn eval_mir_constant( - &mut self, - bx: &Bx, - constant: &mir::Constant<'tcx>, - ) -> Result, ErrorHandled> { - let c = self.monomorphize(&constant.literal); - self.fully_evaluate(bx, c) - } - /// process constant containing SIMD shuffle indices pub fn simd_shuffle_indices( &mut self, diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 55a1eb016e0d0..e17a6e7b03f81 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -76,6 +76,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> OperandRef<'tcx, V> { } let val = match val.val { + ConstValue::Unevaluated(..) => bug!("unevaluated constant in `OperandRef::from_const`"), ConstValue::Param(_) => bug!("encountered a ConstValue::Param in codegen"), ConstValue::Infer(_) => bug!("encountered a ConstValue::Infer in codegen"), ConstValue::Scalar(x) => { diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index 8613464732457..14289381aef45 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -1505,10 +1505,10 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { debug!("add_moved_or_invoked_closure_note: terminator={:?}", terminator); if let TerminatorKind::Call { func: Operand::Constant(box Constant { - literal: ty::LazyConst::Evaluated(ty::Const { + literal: ty::Const { ty: &ty::TyS { sty: ty::TyKind::FnDef(id, _), .. }, .. - }), + }, .. }), args, diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index 65703adfdff70..b8dae98ec64f2 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -471,13 +471,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { Terminator { kind: TerminatorKind::Call { func: Operand::Constant(box Constant { - literal: ty::LazyConst::Evaluated(Const { + literal: Const { ty: &TyS { sty: TyKind::FnDef(id, substs), .. }, .. - }), + }, .. }), .. diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs index 0a0a88e694260..58e567c39a9bb 100644 --- a/src/librustc_mir/borrow_check/nll/renumber.rs +++ b/src/librustc_mir/borrow_check/nll/renumber.rs @@ -80,7 +80,7 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> { debug!("visit_region: region={:?}", region); } - fn visit_const(&mut self, constant: &mut &'tcx ty::LazyConst<'tcx>, _location: Location) { + fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _location: Location) { *constant = self.renumber_regions(&*constant); } 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 5b444ab9690ca..25a3160a498d3 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -28,7 +28,7 @@ use rustc::infer::canonical::QueryRegionConstraint; use rustc::infer::outlives::env::RegionBoundPairs; use rustc::infer::{InferCtxt, InferOk, LateBoundRegionConversionTime, NLLRegionVariableOrigin}; use rustc::infer::type_variable::TypeVariableOrigin; -use rustc::mir::interpret::EvalErrorKind::BoundsCheck; +use rustc::mir::interpret::{EvalErrorKind::BoundsCheck, ConstValue}; use rustc::mir::tcx::PlaceTy; use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext}; use rustc::mir::*; @@ -296,38 +296,34 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { ); } } else { - match *constant.literal { - ty::LazyConst::Unevaluated(def_id, substs) => { - if let Err(terr) = self.cx.fully_perform_op( - location.to_locations(), - ConstraintCategory::Boring, - self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( - constant.ty, def_id, UserSubsts { substs, user_self_ty: None }, - )), - ) { - span_mirbug!( - self, - constant, - "bad constant type {:?} ({:?})", - constant, - terr - ); - } - } - ty::LazyConst::Evaluated(lit) => { - if let ty::FnDef(def_id, substs) = lit.ty.sty { - let tcx = self.tcx(); - - let instantiated_predicates = tcx - .predicates_of(def_id) - .instantiate(tcx, substs); - self.cx.normalize_and_prove_instantiated_predicates( - instantiated_predicates, - location.to_locations(), - ); - } + if let ConstValue::Unevaluated(def_id, substs) = constant.literal.val { + if let Err(terr) = self.cx.fully_perform_op( + location.to_locations(), + ConstraintCategory::Boring, + self.cx.param_env.and(type_op::ascribe_user_type::AscribeUserType::new( + constant.ty, def_id, UserSubsts { substs, user_self_ty: None }, + )), + ) { + span_mirbug!( + self, + constant, + "bad constant type {:?} ({:?})", + constant, + terr + ); } } + if let ty::FnDef(def_id, substs) = constant.literal.ty.sty { + let tcx = self.tcx(); + + let instantiated_predicates = tcx + .predicates_of(def_id) + .instantiate(tcx, substs); + self.cx.normalize_and_prove_instantiated_predicates( + instantiated_predicates, + location.to_locations(), + ); + } } } @@ -418,10 +414,11 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> { constant, location ); - let literal = match constant.literal { - ty::LazyConst::Evaluated(lit) => lit, - ty::LazyConst::Unevaluated(..) => return, - }; + let literal = constant.literal; + + if let ConstValue::Unevaluated(..) = literal.val { + return; + } debug!("sanitize_constant: expected_ty={:?}", literal.ty); diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index f1a82ecef1b1d..9e12a7e6fa931 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -275,13 +275,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { span: expr_span, ty: this.hir.tcx().types.u32, user_ty: None, - literal: this.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated( + literal: this.hir.tcx().mk_const( ty::Const::from_bits( this.hir.tcx(), 0, ty::ParamEnv::empty().and(this.hir.tcx().types.u32), ), - )), + ), })); box AggregateKind::Generator(closure_id, substs, movability) } diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs index 72b92444dece9..0c93984fda806 100644 --- a/src/librustc_mir/build/matches/test.rs +++ b/src/librustc_mir/build/matches/test.rs @@ -299,7 +299,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.into()]); - let method = self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(method)); + let method = self.hir.tcx().mk_const(method); let re_erased = self.hir.tcx().types.re_erased; // take the argument by reference diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs index 2692c24806ff7..d76d3765ac710 100644 --- a/src/librustc_mir/build/misc.rs +++ b/src/librustc_mir/build/misc.rs @@ -33,7 +33,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { span, ty, user_ty: None, - literal: self.hir.tcx().mk_lazy_const(ty::LazyConst::Evaluated(literal)), + literal: self.hir.tcx().mk_const(literal), }; Operand::Constant(constant) } diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index c8e48dea1f34c..ec8c62bb9b4b5 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -201,7 +201,7 @@ impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> { } } - fn visit_const(&mut self, constant: &mut &'tcx ty::LazyConst<'tcx>, _: Location) { + fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) { if let Some(lifted) = self.tcx.lift(constant) { *constant = lifted; } else { diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 71d9398c686b7..79a3e0c5ee248 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -478,7 +478,7 @@ pub fn const_field<'a, 'tcx>( trace!("const_field: {:?}, {:?}", field, value); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); // get the operand again - let op = ecx.const_to_op(value, None).unwrap(); + let op = ecx.eval_const_to_op(value, None).unwrap(); // downcast let down = match variant { None => op, @@ -500,7 +500,7 @@ pub fn const_variant_index<'a, 'tcx>( ) -> VariantIdx { trace!("const_variant_index: {:?}", val); let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env); - let op = ecx.const_to_op(val, None).unwrap(); + let op = ecx.eval_const_to_op(val, None).unwrap(); ecx.read_discriminant(op).unwrap().1 } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index c8c6d73d4536a..b83f048114b06 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -342,9 +342,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } hir::ExprKind::Lit(ref lit) => ExprKind::Literal { - literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated( + literal: cx.tcx.mk_const( cx.const_eval_literal(&lit.node, expr_ty, lit.span, false) - )), + ), user_ty: None, }, @@ -442,9 +442,9 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } else { if let hir::ExprKind::Lit(ref lit) = arg.node { ExprKind::Literal { - literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated( + literal: cx.tcx.mk_const( cx.const_eval_literal(&lit.node, expr_ty, lit.span, true) - )), + ), user_ty: None, } } else { @@ -693,26 +693,29 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }; let source = if let Some((did, offset, var_ty)) = var { - let mk_lazy_const = |literal| Expr { + let mk_const = |literal| Expr { temp_lifetime, ty: var_ty, span: expr.span, kind: ExprKind::Literal { - literal: cx.tcx.mk_lazy_const(literal), + literal: cx.tcx.mk_const(literal), user_ty: None }, }.to_ref(); - let offset = mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits( + let offset = mk_const(ty::Const::from_bits( cx.tcx, offset as u128, cx.param_env.and(var_ty), - ))); + )); match did { Some(did) => { // in case we are offsetting from a computed discriminant // and not the beginning of discriminants (which is always `0`) let substs = InternalSubsts::identity_for_item(cx.tcx(), did); - let lhs = mk_lazy_const(ty::LazyConst::Unevaluated(did, substs)); + let lhs = mk_const(ty::Const { + val: ConstValue::Unevaluated(did, substs), + ty: var_ty, + }); let bin = ExprKind::Binary { op: BinOp::Add, lhs, @@ -852,9 +855,9 @@ fn method_callee<'a, 'gcx, 'tcx>( ty, span, kind: ExprKind::Literal { - literal: cx.tcx().mk_lazy_const(ty::LazyConst::Evaluated( + literal: cx.tcx().mk_const( ty::Const::zero_sized(ty) - )), + ), user_ty, }, } @@ -914,9 +917,9 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def); debug!("convert_path_expr: user_ty={:?}", user_ty); ExprKind::Literal { - literal: cx.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::zero_sized( + literal: cx.tcx.mk_const(ty::Const::zero_sized( cx.tables().node_type(expr.hir_id), - ))), + )), user_ty, } } @@ -930,11 +933,11 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let name = cx.tcx.hir().name(node_id).as_interned_str(); let val = ConstValue::Param(ty::ParamConst::new(index, name)); ExprKind::Literal { - literal: cx.tcx.mk_lazy_const( - ty::LazyConst::Evaluated(ty::Const { + literal: cx.tcx.mk_const( + ty::Const { val, ty: cx.tables().node_type(expr.hir_id), - }) + } ), user_ty: None, } @@ -945,7 +948,10 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, let user_ty = user_substs_applied_to_def(cx, expr.hir_id, &def); debug!("convert_path_expr: (const) user_ty={:?}", user_ty); ExprKind::Literal { - literal: cx.tcx.mk_lazy_const(ty::LazyConst::Unevaluated(def_id, substs)), + literal: cx.tcx.mk_const(ty::Const { + val: ConstValue::Unevaluated(def_id, substs), + ty: cx.tcx.type_of(def_id), + }), user_ty, } }, diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs index c0f3989b4ba97..71c6489d63f0d 100644 --- a/src/librustc_mir/hair/cx/mod.rs +++ b/src/librustc_mir/hair/cx/mod.rs @@ -106,8 +106,8 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { self.tcx.types.usize } - pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::LazyConst<'tcx> { - self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_usize(self.tcx, value))) + pub fn usize_literal(&mut self, value: u64) -> &'tcx ty::Const<'tcx> { + self.tcx.mk_const(ty::Const::from_usize(self.tcx, value)) } pub fn bool_ty(&mut self) -> Ty<'tcx> { @@ -118,12 +118,12 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> { self.tcx.mk_unit() } - pub fn true_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> { - self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, true))) + pub fn true_literal(&mut self) -> &'tcx ty::Const<'tcx> { + self.tcx.mk_const(ty::Const::from_bool(self.tcx, true)) } - pub fn false_literal(&mut self) -> &'tcx ty::LazyConst<'tcx> { - self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bool(self.tcx, false))) + pub fn false_literal(&mut self) -> &'tcx ty::Const<'tcx> { + self.tcx.mk_const(ty::Const::from_bool(self.tcx, false)) } pub fn const_eval_literal( diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 385249ec1c13b..3a38876bb6802 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -9,7 +9,7 @@ use rustc::hir::def_id::DefId; use rustc::infer::canonical::Canonical; use rustc::middle::region; use rustc::ty::subst::SubstsRef; -use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, LazyConst, UserType}; +use rustc::ty::{AdtDef, UpvarSubsts, Ty, Const, UserType}; use rustc::ty::layout::VariantIdx; use rustc::hir; use syntax_pos::Span; @@ -289,7 +289,7 @@ pub enum ExprKind<'tcx> { movability: Option, }, Literal { - literal: &'tcx LazyConst<'tcx>, + literal: &'tcx Const<'tcx>, user_ty: Option>>, }, InlineAsm { diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 44bcb9de0e157..88d1eb2ee0be0 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -222,7 +222,7 @@ impl<'a, 'tcx> LiteralExpander<'a, 'tcx> { assert_eq!(t, u); ConstValue::Slice( Scalar::Ptr(p), - n.map_evaluated(|val| val.val.try_to_scalar()) + n.val.try_to_scalar() .unwrap() .to_usize(&self.tcx) .unwrap(), diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index ad7b45d89453a..8614be8d407b1 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -13,7 +13,7 @@ use crate::hair::constant::*; use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::{UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; -use rustc::ty::{self, DefIdTree, Region, TyCtxt, AdtDef, Ty, Lift, UserType}; +use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree}; use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations}; use rustc::ty::subst::{SubstsRef, Kind}; use rustc::ty::layout::VariantIdx; @@ -1233,9 +1233,6 @@ pub fn compare_const_vals<'a, 'gcx, 'tcx>( return fallback(); } - let tcx = tcx.global_tcx(); - let (a, b, ty) = (a, b, ty).lift_to_tcx(tcx).unwrap(); - // FIXME: This should use assert_bits(ty) instead of use_bits // but triggers possibly bugs due to mismatching of arrays and slices if let (Some(a), Some(b)) = (a.to_bits(tcx, ty), b.to_bits(tcx, ty)) { @@ -1251,11 +1248,12 @@ pub fn compare_const_vals<'a, 'gcx, 'tcx>( let r = ::rustc_apfloat::ieee::Double::from_bits(b); l.partial_cmp(&r) } - ty::Int(_) => { - let layout = tcx.layout_of(ty).ok()?; - assert!(layout.abi.is_signed()); - let a = sign_extend(a, layout.size); - let b = sign_extend(b, layout.size); + ty::Int(ity) => { + use rustc::ty::layout::{Integer, IntegerExt}; + use syntax::attr::SignedInt; + let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); + let a = sign_extend(a, size); + let b = sign_extend(b, size); Some((a as i128).cmp(&(b as i128))) } _ => Some(a.cmp(&b)), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 206eaaf1787c5..70511075e87c9 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -547,7 +547,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> Move(ref place) => self.eval_place_to_op(place, layout)?, - Constant(ref constant) => self.eval_lazy_const_to_op(*constant.literal, layout)?, + Constant(ref constant) => self.eval_const_to_op(*constant.literal, layout)?, }; trace!("{:?}: {:?}", mir_op, *op); Ok(op) @@ -563,36 +563,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> .collect() } - // Used when Miri runs into a constant, and by const propagation. - crate fn eval_lazy_const_to_op( - &self, - val: ty::LazyConst<'tcx>, - layout: Option>, - ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { - trace!("const_to_op: {:?}", val); - match val { - ty::LazyConst::Unevaluated(def_id, substs) => { - let instance = self.resolve(def_id, substs)?; - return Ok(OpTy::from(self.const_eval_raw(GlobalId { - instance, - promoted: None, - })?)); - }, - ty::LazyConst::Evaluated(c) => self.const_to_op(c, layout), - } - } - // Used when the miri-engine runs into a constant and for extracting information from constants // in patterns via the `const_eval` module - crate fn const_to_op( + crate fn eval_const_to_op( &self, val: ty::Const<'tcx>, layout: Option>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { - let val = self.monomorphize(val)?; - let layout = from_known_layout(layout, || { - self.layout_of(val.ty) - })?; let op = match val.val { ConstValue::Param(_) | ConstValue::Infer(_) => bug!(), ConstValue::ByRef(ptr, alloc) => { @@ -609,7 +586,17 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> )).with_default_tag(), ConstValue::Scalar(x) => Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag(), + ConstValue::Unevaluated(def_id, substs) => { + let instance = self.resolve(def_id, substs)?; + return Ok(OpTy::from(self.const_eval_raw(GlobalId { + instance, + promoted: None, + })?)); + }, }; + let layout = from_known_layout(layout, || { + self.layout_of(self.monomorphize(val.ty)?) + })?; Ok(OpTy { op, layout, diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 307cee5d97217..4fe47a9666a68 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -381,7 +381,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let param_env = ty::ParamEnv::reveal_all(); if let Ok(val) = tcx.const_eval(param_env.and(cid)) { - collect_const(tcx, val, &mut neighbors); + collect_const(tcx, val, InternalSubsts::empty(), &mut neighbors); } } MonoItem::Fn(instance) => { @@ -468,15 +468,7 @@ fn check_type_length_limit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance<'tcx>) { let type_length = instance.substs.types().flat_map(|ty| ty.walk()).count(); - let const_length = instance.substs.consts() - .flat_map(|ct| { - let ty = match ct { - ty::LazyConst::Evaluated(ct) => ct.ty, - ty::LazyConst::Unevaluated(def_id, _) => tcx.type_of(*def_id), - }; - ty.walk() - }) - .count(); + let const_length = instance.substs.consts().flat_map(|ct| ct.ty.walk()).count(); debug!(" => type length={}, const length={}", type_length, const_length); // Rust code can easily create exponentially-long types using only a @@ -606,10 +598,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { self.super_rvalue(rvalue, location); } - fn visit_const(&mut self, constant: &&'tcx ty::LazyConst<'tcx>, location: Location) { + fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, location: Location) { debug!("visiting const {:?} @ {:?}", *constant, location); - collect_lazy_const(self.tcx, constant, self.param_substs, self.output); + collect_const(self.tcx, **constant, self.param_substs, self.output); self.super_const(constant); } @@ -1013,7 +1005,7 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { let param_env = ty::ParamEnv::reveal_all(); if let Ok(val) = self.tcx.const_eval(param_env.and(cid)) { - collect_const(self.tcx, val, &mut self.output); + collect_const(self.tcx, val, InternalSubsts::empty(), &mut self.output); } } hir::ItemKind::Fn(..) => { @@ -1224,7 +1216,7 @@ fn collect_neighbours<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, promoted: Some(i), }; match tcx.const_eval(param_env.and(cid)) { - Ok(val) => collect_const(tcx, val, output), + Ok(val) => collect_const(tcx, val, instance.substs, output), Err(ErrorHandled::Reported) => {}, Err(ErrorHandled::TooGeneric) => span_bug!( mir.promoted[i].span, "collection encountered polymorphic constant", @@ -1242,43 +1234,10 @@ fn def_id_to_string<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, output } -fn collect_lazy_const<'a, 'tcx>( - tcx: TyCtxt<'a, 'tcx, 'tcx>, - constant: &ty::LazyConst<'tcx>, - param_substs: SubstsRef<'tcx>, - output: &mut Vec>, -) { - let (def_id, substs) = match *constant { - ty::LazyConst::Evaluated(c) => return collect_const(tcx, c, output), - ty::LazyConst::Unevaluated(did, substs) => (did, substs), - }; - let param_env = ty::ParamEnv::reveal_all(); - let substs = tcx.subst_and_normalize_erasing_regions( - param_substs, - param_env, - &substs, - ); - let instance = ty::Instance::resolve(tcx, - param_env, - def_id, - substs).unwrap(); - - let cid = GlobalId { - instance, - promoted: None, - }; - match tcx.const_eval(param_env.and(cid)) { - Ok(val) => collect_const(tcx, val, output), - Err(ErrorHandled::Reported) => {}, - Err(ErrorHandled::TooGeneric) => span_bug!( - tcx.def_span(def_id), "collection encountered polymorphic constant", - ), - } -} - fn collect_const<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, constant: ty::Const<'tcx>, + param_substs: SubstsRef<'tcx>, output: &mut Vec>, ) { debug!("visiting const {:?}", constant); @@ -1292,6 +1251,30 @@ fn collect_const<'a, 'tcx>( collect_miri(tcx, id, output); } } + ConstValue::Unevaluated(did, substs) => { + let param_env = ty::ParamEnv::reveal_all(); + let substs = tcx.subst_and_normalize_erasing_regions( + param_substs, + param_env, + &substs, + ); + let instance = ty::Instance::resolve(tcx, + param_env, + did, + substs).unwrap(); + + let cid = GlobalId { + instance, + promoted: None, + }; + match tcx.const_eval(param_env.and(cid)) { + Ok(val) => collect_const(tcx, val, param_substs, output), + Err(ErrorHandled::Reported) => {}, + Err(ErrorHandled::TooGeneric) => span_bug!( + tcx.def_span(did), "collection encountered polymorphic constant", + ), + } + } _ => {}, } } diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index 68d13bf2dcb24..51ba690d3a14b 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -3,7 +3,7 @@ use rustc::hir; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::interpret::ConstValue; use rustc::session::config::OptLevel; -use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, LazyConst, ParamConst}; +use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, ParamConst}; use rustc::ty::subst::{SubstsRef, InternalSubsts}; use syntax::ast; use syntax::attr::InlineAttr; @@ -395,21 +395,17 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { } // FIXME(const_generics): handle debug printing. - pub fn push_const_name(&self, c: &LazyConst<'tcx>, output: &mut String, debug: bool) { - match c { - LazyConst::Unevaluated(..) => output.push_str("_: _"), - LazyConst::Evaluated(Const { ty, val }) => { - match val { - ConstValue::Infer(..) => output.push_str("_"), - ConstValue::Param(ParamConst { name, .. }) => { - write!(output, "{}", name).unwrap(); - } - _ => write!(output, "{:?}", c).unwrap(), - } - output.push_str(": "); - self.push_type_name(ty, output, debug); + pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) { + match c.val { + ConstValue::Infer(..) => output.push_str("_"), + ConstValue::Param(ParamConst { name, .. }) => { + write!(output, "{}", name).unwrap(); } + ConstValue::Unevaluated(..) => output.push_str("_: _"), + _ => write!(output, "{:?}", c).unwrap(), } + output.push_str(": "); + self.push_type_name(c.ty, output, debug); } pub fn push_def_path(&self, diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 1c6b1450be862..f1fbc80edfb4b 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -458,9 +458,9 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { span: self.span, ty: func_ty, user_ty: None, - literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated( + literal: tcx.mk_const( ty::Const::zero_sized(func_ty), - )), + ), }); let ref_loc = self.make_place( @@ -520,9 +520,9 @@ impl<'a, 'tcx> CloneShimBuilder<'a, 'tcx> { span: self.span, ty: self.tcx.types.usize, user_ty: None, - literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated( + literal: self.tcx.mk_const( ty::Const::from_usize(self.tcx, value), - )), + ), } } @@ -762,9 +762,9 @@ fn build_call_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span, ty, user_ty: None, - literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated( + literal: tcx.mk_const( ty::Const::zero_sized(ty) - )), + ), }), vec![rcvr]) } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 23d8138efccaf..d816968442058 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -253,7 +253,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> { source_info: SourceInfo, ) -> Option> { self.ecx.tcx.span = source_info.span; - match self.ecx.eval_lazy_const_to_op(*c.literal, None) { + match self.ecx.eval_const_to_op(*c.literal, None) { Ok(op) => { Some((op, c.span)) }, diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index 32c027d90a0ce..d5098bc1db2b1 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -533,9 +533,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { span, ty: self.tcx.types.bool, user_ty: None, - literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated( + literal: self.tcx.mk_const( ty::Const::from_bool(self.tcx, val), - )), + ), }))) } diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs index 9494d4b1f6c39..a853f8d92beae 100644 --- a/src/librustc_mir/transform/erase_regions.rs +++ b/src/librustc_mir/transform/erase_regions.rs @@ -32,7 +32,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> { *region = self.tcx.types.re_erased; } - fn visit_const(&mut self, constant: &mut &'tcx ty::LazyConst<'tcx>, _: Location) { + fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) { *constant = self.tcx.erase_regions(constant); } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 1f59802f8c6c0..33645b5758947 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -198,11 +198,11 @@ impl<'a, 'tcx> TransformVisitor<'a, 'tcx> { span: source_info.span, ty: self.tcx.types.u32, user_ty: None, - literal: self.tcx.mk_lazy_const(ty::LazyConst::Evaluated(ty::Const::from_bits( + literal: self.tcx.mk_const(ty::Const::from_bits( self.tcx, state_disc.into(), ty::ParamEnv::empty().and(self.tcx.types.u32) - ))), + )), }); Statement { source_info, @@ -729,9 +729,9 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: mir.span, ty: tcx.types.bool, user_ty: None, - literal: tcx.mk_lazy_const(ty::LazyConst::Evaluated( + literal: tcx.mk_const( ty::Const::from_bool(tcx, false), - )), + ), }), expected: true, msg: message, diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index 001a61959c2dd..e96689809add7 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -16,6 +16,7 @@ use rustc::ty::{self, TyCtxt, Ty, TypeFoldable}; use rustc::ty::cast::CastTy; use rustc::ty::query::Providers; use rustc::mir::*; +use rustc::mir::interpret::ConstValue; use rustc::mir::traversal::ReversePostorder; use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext}; use rustc::middle::lang_items; @@ -199,12 +200,12 @@ trait Qualif { Operand::Move(ref place) => Self::in_place(cx, place), Operand::Constant(ref constant) => { - if let ty::LazyConst::Unevaluated(def_id, _) = constant.literal { + if let ConstValue::Unevaluated(def_id, _) = constant.literal.val { // Don't peek inside trait associated constants. - if cx.tcx.trait_of_item(*def_id).is_some() { + if cx.tcx.trait_of_item(def_id).is_some() { Self::in_any_value_of_ty(cx, constant.ty).unwrap_or(false) } else { - let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(*def_id); + let (bits, _) = cx.tcx.at(constant.span).mir_const_qualif(def_id); let qualif = PerQualif::decode_from_bits(bits).0[Self::IDX]; diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs index 3c4d1227a691c..db73e829c53a7 100644 --- a/src/librustc_mir/transform/simplify_branches.rs +++ b/src/librustc_mir/transform/simplify_branches.rs @@ -30,7 +30,7 @@ impl MirPass for SimplifyBranches { discr: Operand::Constant(ref c), switch_ty, ref values, ref targets, .. } => { let switch_ty = ParamEnv::empty().and(switch_ty); - let constant = c.literal.map_evaluated(|c| c.assert_bits(tcx, switch_ty)); + let constant = c.literal.assert_bits(tcx, switch_ty); if let Some(constant) = constant { let (otherwise, targets) = targets.split_last().unwrap(); let mut ret = TerminatorKind::Goto { target: *otherwise }; @@ -47,7 +47,7 @@ impl MirPass for SimplifyBranches { }, TerminatorKind::Assert { target, cond: Operand::Constant(ref c), expected, .. - } if (c.literal.map_evaluated(|e| e.assert_bool(tcx)) == Some(true)) == expected => + } if (c.literal.assert_bool(tcx) == Some(true)) == expected => TerminatorKind::Goto { target }, TerminatorKind::FalseEdges { real_target, .. } => { TerminatorKind::Goto { target: real_target } diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs index 26fa8d6d1f0bf..37b38338ab9a7 100644 --- a/src/librustc_mir/util/elaborate_drops.rs +++ b/src/librustc_mir/util/elaborate_drops.rs @@ -966,9 +966,9 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D> span: self.source_info.span, ty: self.tcx().types.usize, user_ty: None, - literal: self.tcx().mk_lazy_const(ty::LazyConst::Evaluated( + literal: self.tcx().mk_const( ty::Const::from_usize(self.tcx(), val.into()) - )), + ), }) } diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c7c77d351a75f..4663f90eb3e4b 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -417,21 +417,12 @@ impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ExtraComments<'cx, 'gcx, 'tcx> { self.push(&format!("+ literal: {:?}", literal)); } - fn visit_const(&mut self, constant: &&'tcx ty::LazyConst<'tcx>, _: Location) { + fn visit_const(&mut self, constant: &&'tcx ty::Const<'tcx>, _: Location) { self.super_const(constant); - match constant { - ty::LazyConst::Evaluated(constant) => { - let ty::Const { ty, val, .. } = constant; - self.push("ty::Const"); - self.push(&format!("+ ty: {:?}", ty)); - self.push(&format!("+ val: {:?}", val)); - }, - ty::LazyConst::Unevaluated(did, substs) => { - self.push("ty::LazyConst::Unevaluated"); - self.push(&format!("+ did: {:?}", did)); - self.push(&format!("+ substs: {:?}", substs)); - }, - } + let ty::Const { ty, val, .. } = constant; + self.push("ty::Const"); + self.push(&format!("+ ty: {:?}", ty)); + self.push(&format!("+ val: {:?}", val)); } fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 6420f20a3ea29..334f510d10dad 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -288,13 +288,10 @@ impl context::ContextOps> for ChalkContext<'cx, 'gcx> { } _ => false, }, - UnpackedKind::Const(ct) => match ct { - ty::LazyConst::Evaluated(ty::Const { - val: ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)), - .. - }) => { - debug_assert_eq!(*debruijn, ty::INNERMOST); - cvar == *bound_ct + UnpackedKind::Const(ct) => match ct.val { + ConstValue::Infer(InferConst::Canonical(debruijn, bound_ct)) => { + debug_assert_eq!(debruijn, ty::INNERMOST); + cvar == bound_ct } _ => false, } diff --git a/src/librustc_traits/chalk_context/program_clauses.rs b/src/librustc_traits/chalk_context/program_clauses.rs index 3f88d0e08b46a..8d5d2b8a9a255 100644 --- a/src/librustc_traits/chalk_context/program_clauses.rs +++ b/src/librustc_traits/chalk_context/program_clauses.rs @@ -239,7 +239,7 @@ fn wf_clause_for_slice<'tcx>(tcx: ty::TyCtxt<'_, '_, 'tcx>) -> Clauses<'tcx> { fn wf_clause_for_array<'tcx>( tcx: ty::TyCtxt<'_, '_, 'tcx>, - length: &'tcx ty::LazyConst<'tcx> + length: &'tcx ty::Const<'tcx> ) -> Clauses<'tcx> { let ty = generic_types::bound(tcx, 0); let array_ty = tcx.mk_ty(ty::Array(ty, length)); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 9ca75566b4280..df8b1bcfe706e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1870,16 +1870,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { &self, ast_const: &hir::AnonConst, ty: Ty<'tcx> - ) -> &'tcx ty::LazyConst<'tcx> { + ) -> &'tcx ty::Const<'tcx> { debug!("ast_const_to_const(id={:?}, ast_const={:?})", ast_const.hir_id, ast_const); let tcx = self.tcx(); let def_id = tcx.hir().local_def_id_from_hir_id(ast_const.hir_id); - let mut lazy_const = ty::LazyConst::Unevaluated( - def_id, - InternalSubsts::identity_for_item(tcx, def_id), - ); + let mut const_ = ty::Const { + val: ConstValue::Unevaluated( + def_id, + InternalSubsts::identity_for_item(tcx, def_id), + ), + ty, + }; let expr = &tcx.hir().body(ast_const.body).value; if let ExprKind::Path(ref qpath) = expr.node { @@ -1891,15 +1894,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let generics = tcx.generics_of(item_def_id); let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)]; let name = tcx.hir().name(node_id).as_interned_str(); - lazy_const = ty::LazyConst::Evaluated(ty::Const { - val: ConstValue::Param(ty::ParamConst::new(index, name)), - ty, - }) + const_.val = ConstValue::Param(ty::ParamConst::new(index, name)); } } }; - tcx.mk_lazy_const(lazy_const) + tcx.mk_const(const_) } pub fn impl_trait_ty_to_ty( diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fa4bb02189f20..ba6894b92fa08 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2424,7 +2424,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty } - pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::LazyConst<'tcx> { + pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { AstConv::ast_const_to_const(self, ast_c, ty) } @@ -4594,7 +4594,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if element_ty.references_error() { tcx.types.err } else if let Ok(count) = count { - tcx.mk_ty(ty::Array(t, tcx.mk_lazy_const(ty::LazyConst::Evaluated(count)))) + tcx.mk_ty(ty::Array(t, tcx.mk_const(count))) } else { tcx.types.err } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 1f7e05de18bcf..0675feade53ef 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -506,11 +506,8 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( true } - fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool { - if let ty::LazyConst::Evaluated(ty::Const { - val: ConstValue::Param(param), - .. - }) = c { + fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool { + if let ConstValue::Param(param) = c.val { self.params.insert(param.index); } c.super_visit_with(self) @@ -678,11 +675,8 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( } } - ty::subst::UnpackedKind::Const(ct) => match ct { - ty::LazyConst::Evaluated(ty::Const { - val: ConstValue::Param(_), - .. - }) => {} + ty::subst::UnpackedKind::Const(ct) => match ct.val { + ConstValue::Param(_) => {} _ => { tcx.sess .struct_span_err( diff --git a/src/librustc_typeck/constrained_type_params.rs b/src/librustc_typeck/constrained_type_params.rs index 4b922c3403886..c8687f5e455fd 100644 --- a/src/librustc_typeck/constrained_type_params.rs +++ b/src/librustc_typeck/constrained_type_params.rs @@ -78,12 +78,9 @@ impl<'tcx> TypeVisitor<'tcx> for ParameterCollector { false } - fn visit_const(&mut self, c: &'tcx ty::LazyConst<'tcx>) -> bool { - if let ty::LazyConst::Evaluated(ty::Const { - val: ConstValue::Param(data), - .. - }) = c { - self.parameters.push(Parameter::from(*data)); + fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool { + if let ConstValue::Param(data) = c.val { + self.parameters.push(Parameter::from(data)); } false } diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs index c18f9fd102f10..20eae5d88351b 100644 --- a/src/librustc_typeck/variance/constraints.rs +++ b/src/librustc_typeck/variance/constraints.rs @@ -452,7 +452,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { fn add_constraints_from_const( &mut self, current: &CurrentItem, - ct: &ty::LazyConst<'tcx>, + ct: &ty::Const<'tcx>, variance: VarianceTermPtr<'a> ) { debug!( @@ -461,11 +461,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { variance ); - if let ty::LazyConst::Evaluated(ct) = ct { - self.add_constraints_from_ty(current, ct.ty, variance); - if let ConstValue::Param(ref data) = ct.val { - self.add_constraint(current, data.index, variance); - } + self.add_constraints_from_ty(current, ct.ty, variance); + if let ConstValue::Param(ref data) = ct.val { + self.add_constraint(current, data.index, variance); } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3aea661f6bec5..c51c8027de64e 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -16,7 +16,7 @@ use rustc::infer::region_constraints::{RegionConstraintData, Constraint}; use rustc::middle::resolve_lifetime as rl; use rustc::middle::lang_items; use rustc::middle::stability; -use rustc::mir::interpret::GlobalId; +use rustc::mir::interpret::{GlobalId, ConstValue}; use rustc::hir::{self, GenericArg, HirVec}; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; @@ -2551,7 +2551,7 @@ impl Clean for hir::Ty { promoted: None }; let length = match cx.tcx.const_eval(param_env.and(cid)) { - Ok(length) => print_const(cx, ty::LazyConst::Evaluated(length)), + Ok(length) => print_const(cx, length), Err(_) => "_".to_string(), }; Array(box ty.clean(cx), length) @@ -2739,14 +2739,14 @@ impl<'tcx> Clean for Ty<'tcx> { ty::Slice(ty) => Slice(box ty.clean(cx)), ty::Array(ty, n) => { let mut n = *cx.tcx.lift(&n).expect("array lift failed"); - if let ty::LazyConst::Unevaluated(def_id, substs) = n { + if let ConstValue::Unevaluated(def_id, substs) = n.val { let param_env = cx.tcx.param_env(def_id); let cid = GlobalId { instance: ty::Instance::new(def_id, substs), promoted: None }; if let Ok(new_n) = cx.tcx.const_eval(param_env.and(cid)) { - n = ty::LazyConst::Evaluated(new_n); + n = new_n; } }; let n = print_const(cx, n); @@ -3900,16 +3900,16 @@ fn name_from_pat(p: &hir::Pat) -> String { } } -fn print_const(cx: &DocContext<'_>, n: ty::LazyConst<'_>) -> String { - match n { - ty::LazyConst::Unevaluated(def_id, _) => { +fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { + match n.val { + ConstValue::Unevaluated(def_id, _) => { if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) { print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id)) } else { inline::print_inlined_const(cx, def_id) } }, - ty::LazyConst::Evaluated(n) => { + _ => { let mut s = String::new(); ::rustc::mir::fmt_const_val(&mut s, n).expect("fmt_const_val failed"); // array lengths are obviously usize