diff options
| author | bors <bors@rust-lang.org> | 2019-03-17 11:17:03 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-03-17 11:17:03 +0000 |
| commit | 070cebd0aa76702eaaf7c7f340615805f661e937 (patch) | |
| tree | 4d66a96601fd92b2ddbbb325c9fd9af37014f7db | |
| parent | 7cf074a1e655ac07d04d045667278fa1a9970b93 (diff) | |
| parent | 5cd28066214a4a255bac6655c20bf05cb95730fd (diff) | |
| download | rust-070cebd0aa76702eaaf7c7f340615805f661e937.tar.gz rust-070cebd0aa76702eaaf7c7f340615805f661e937.zip | |
Auto merge of #59178 - oli-obk:lazy_const, r=eddyb
Revert the `LazyConst` PR The introduction of `LazyConst` did not actually achieve the code simplicity improvements that were the main reason it was introduced. Especially in the presence of const generics, the differences between the "levels of evaluatedness" of a constant become less clear. As it can be seen by the changes in this PR, further simplifications were possible by folding `LazyConst` back into `ConstValue`. We have been able to keep all the advantages gained during the `LazyConst` refactoring (like `const_eval` not returning an interned value, thus making all the `match` code simpler and more performant). fixes https://github.com/rust-lang/rust/issues/59209 r? @eddyb @varkor
56 files changed, 367 insertions, 562 deletions
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 9620ac95d86..7b47c02de1b 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 718b506d051..9f2027e7d05 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<UserTypeAnnotationIndex>, - 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 28e816f1343..8bc0075c477 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 ab6acc66213..360e2323b64 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 8a30c18d6e5..9940249da8b 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 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); diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs index 2bb68dc687c..a1d44b228a5 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<ty::Const<'tcx>, 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<ty::Const<'tcx>, 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 55a1eb016e0..e17a6e7b03f 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 86134647324..14289381aef 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 65703adfdff..b8dae98ec64 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 0a0a88e6942..58e567c39a9 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 5b444ab9690..25a3160a498 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 f1a82ecef1b..9e12a7e6fa9 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 72b92444dec..0c93984fda8 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 2692c24806f..d76d3765ac7 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 c8e48dea1f3..ec8c62bb9b4 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 71d9398c686..79a3e0c5ee2 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 c8c6d73d453..b83f048114b 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 c0f3989b4ba..71c6489d63f 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 385249ec1c1..3a38876bb68 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<hir::GeneratorMovability>, }, Literal { - literal: &'tcx LazyConst<'tcx>, + literal: &'tcx Const<'tcx>, user_ty: Option<Canonical<'tcx, UserType<'tcx>>>, }, InlineAsm { diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 44bcb9de0e1..88d1eb2ee0b 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 ad7b45d8945..8614be8d407 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 206eaaf1787..70511075e87 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<TyLayout<'tcx>>, - ) -> 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<TyLayout<'tcx>>, ) -> 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 307cee5d972..4fe47a9666a 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<MonoItem<'tcx>>, -) { - 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<MonoItem<'tcx>>, ) { 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 68d13bf2dcb..51ba690d3a1 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 1c6b1450be8..f1fbc80edfb 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 23d8138efcc..d8169684420 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<Const<'tcx>> { 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 32c027d90a0..d5098bc1db2 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 9494d4b1f6c..a853f8d92be 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 1f59802f8c6..33645b57589 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 001a61959c2..e96689809ad 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 3c4d1227a69..db73e829c53 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 26fa8d6d1f0..37b38338ab9 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 c7c77d351a7..4663f90eb3e 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 6420f20a3ea..334f510d10d 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -288,13 +288,10 @@ impl context::ContextOps<ChalkArenas<'gcx>> 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 3f88d0e08b4..8d5d2b8a9a2 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 9ca75566b42..df8b1bcfe70 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 fa4bb02189f..ba6894b92fa 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 1f7e05de18b..0675feade53 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 4b922c34038..c8687f5e455 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 c18f9fd102f..20eae5d8835 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 3aea661f6be..c51c8027de6 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<Type> 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<Type> 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 |
