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