diff options
| author | Oliver Schneider <github35764891676564198441@oli-obk.de> | 2018-06-25 20:53:02 +0200 |
|---|---|---|
| committer | Oliver Schneider <github35764891676564198441@oli-obk.de> | 2018-06-28 11:04:25 +0200 |
| commit | 4bb9648b27e2c9f9efdb9e29a0d90b229aaff562 (patch) | |
| tree | 396538df8e178c1d5ddc1359a399651fc1373c89 /src | |
| parent | 221a499bf111c02f0d2cffa3ffa520d842d1877d (diff) | |
| download | rust-4bb9648b27e2c9f9efdb9e29a0d90b229aaff562.tar.gz rust-4bb9648b27e2c9f9efdb9e29a0d90b229aaff562.zip | |
Merge `ConstVal` and `ConstValue`
Diffstat (limited to 'src')
35 files changed, 201 insertions, 338 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 33322993b1d..6cc61d74800 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -60,7 +60,7 @@ //! user of the `DepNode` API of having to know how to compute the expected //! fingerprint for a given set of node parameters. -use mir::interpret::{GlobalId, ConstValue}; +use mir::interpret::GlobalId; use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use hir::map::DefPathHash; use hir::{HirId, ItemLocalId}; @@ -75,7 +75,7 @@ use traits::query::{ CanonicalPredicateGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpNormalizeGoal, }; use ty::{TyCtxt, FnSig, Instance, InstanceDef, - ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty}; + ParamEnv, ParamEnvAnd, Predicate, PolyFnSig, PolyTraitRef, Ty, self}; use ty::subst::Substs; // erase!() just makes tokens go away. It's used to specify which macro argument @@ -632,7 +632,7 @@ define_dep_nodes!( <'tcx> // queries). Making them anonymous avoids hashing the result, which // may save a bit of time. [anon] EraseRegionsTy { ty: Ty<'tcx> }, - [anon] ConstValueToAllocation { val: ConstValue<'tcx>, ty: Ty<'tcx> }, + [anon] ConstValueToAllocation { val: &'tcx ty::Const<'tcx> }, [input] Freevars(DefId), [input] MaybeUnusedTraitImport(DefId), diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index d3280a9130e..4eb677732c2 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -370,11 +370,11 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for ty::FieldDef { } impl<'a, 'gcx> HashStable<StableHashingContext<'a>> -for ::mir::interpret::ConstVal<'gcx> { +for ::mir::interpret::ConstValue<'gcx> { fn hash_stable<W: StableHasherResult>(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher<W>) { - use mir::interpret::ConstVal::*; + use mir::interpret::ConstValue::*; mem::discriminant(self).hash_stable(hcx, hasher); @@ -383,23 +383,6 @@ for ::mir::interpret::ConstVal<'gcx> { def_id.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); } - Value(ref value) => { - value.hash_stable(hcx, hasher); - } - } - } -} - -impl<'a, 'gcx> HashStable<StableHashingContext<'a>> -for ::mir::interpret::ConstValue<'gcx> { - fn hash_stable<W: StableHasherResult>(&self, - hcx: &mut StableHashingContext<'a>, - hasher: &mut StableHasher<W>) { - use mir::interpret::ConstValue::*; - - mem::discriminant(self).hash_stable(hcx, hasher); - - match *self { Scalar(val) => { val.hash_stable(hcx, hasher); } diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index dca1c12b51d..3291d6bf152 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -11,12 +11,8 @@ use super::{ use backtrace::Backtrace; - -use hir::def_id::DefId; use ty; -use ty::subst::Substs; use ty::query::TyCtxtAt; -use mir::interpret::ConstValue; use errors::DiagnosticBuilder; use syntax_pos::Span; @@ -24,12 +20,6 @@ use syntax::ast; pub type ConstEvalResult<'tcx> = Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>; -#[derive(Copy, Clone, Debug, Hash, RustcEncodable, RustcDecodable, Eq, PartialEq, Ord, PartialOrd)] -pub enum ConstVal<'tcx> { - Unevaluated(DefId, &'tcx Substs<'tcx>), - Value(ConstValue<'tcx>), -} - #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct ConstEvalErr<'tcx> { pub span: Span, diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index bd8970f5ea6..018c2446054 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -9,7 +9,7 @@ mod error; mod value; pub use self::error::{ - EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstVal, ConstEvalErr, struct_error, + EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error, FrameInfo, ConstEvalResult, }; diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 9e3d4e60603..24595c93282 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -2,13 +2,19 @@ use ty::layout::{Align, HasDataLayout, Size}; use ty; +use ty::subst::Substs; +use hir::def_id::DefId; use super::{EvalResult, Pointer, PointerArithmetic, Allocation}; /// Represents a constant value in Rust. ByVal and ScalarPair are optimizations which /// matches Value's optimizations for easy conversions between these two types -#[derive(Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash)] pub enum ConstValue<'tcx> { + /// Never returned from the `const_eval` query, but the HIR contains these frequently in order + /// to allow HIR creation to happen for everything before needing to be able to run constant + /// evaluation + Unevaluated(DefId, &'tcx Substs<'tcx>), /// Used only for types with layout::abi::Scalar ABI and ZSTs which use Scalar::undef() Scalar(Scalar), /// Used only for types with layout::abi::ScalarPair @@ -30,6 +36,7 @@ impl<'tcx> ConstValue<'tcx> { #[inline] pub fn to_byval_value(&self) -> Option<Value> { match *self { + ConstValue::Unevaluated(..) | ConstValue::ByRef(..) => None, ConstValue::ScalarPair(a, b) => Some(Value::ScalarPair(a, b)), ConstValue::Scalar(val) => Some(Value::Scalar(val)), @@ -44,7 +51,8 @@ impl<'tcx> ConstValue<'tcx> { #[inline] pub fn to_scalar(&self) -> Option<Scalar> { match *self { - ConstValue::ByRef(..) => None, + ConstValue::Unevaluated(..) | + ConstValue::ByRef(..) | ConstValue::ScalarPair(..) => None, ConstValue::Scalar(val) => Some(val), } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 31d5ef2e160..2198e3f6b31 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2162,18 +2162,12 @@ impl<'tcx> Debug for Literal<'tcx> { } } -/// Write a `ConstVal` in a way closer to the original source code than the `Debug` output. +/// Write a `ConstValue` in a way closer to the original source code than the `Debug` output. pub fn fmt_const_val<W: Write>(fmt: &mut W, const_val: &ty::Const) -> fmt::Result { - use mir::interpret::ConstVal; - match const_val.val { - ConstVal::Unevaluated(..) => write!(fmt, "{:?}", const_val), - ConstVal::Value(val) => { - if let Some(value) = val.to_byval_value() { - print_miri_value(value, const_val.ty, fmt) - } else { - write!(fmt, "{:?}:{}", val, const_val.ty) - } - } + if let Some(value) = const_val.to_byval_value() { + print_miri_value(value, const_val.ty, fmt) + } else { + write!(fmt, "{:?}:{}", const_val.val, const_val.ty) } } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 73d288761a0..c49bcbf8f03 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -28,7 +28,7 @@ use super::util; use hir::def_id::DefId; use infer::{InferCtxt, InferOk}; use infer::type_variable::TypeVariableOrigin; -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use mir::interpret::{GlobalId}; use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap}; use syntax::symbol::Symbol; @@ -426,7 +426,7 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a, } fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - if let ConstVal::Unevaluated(def_id, substs) = constant.val { + 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_skol() { diff --git a/src/librustc/traits/query/normalize.rs b/src/librustc/traits/query/normalize.rs index c33f028ae1e..bc2f1b7f6c7 100644 --- a/src/librustc/traits/query/normalize.rs +++ b/src/librustc/traits/query/normalize.rs @@ -194,7 +194,7 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx } fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - if let ConstVal::Unevaluated(def_id, substs) = constant.val { + 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_skol() { diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index 3c798648e19..3718c436b3a 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use ty::subst::Substs; use ty::{self, Ty, TypeFlags, TypeFoldable}; @@ -233,12 +233,9 @@ impl FlagComputation { fn add_const(&mut self, constant: &ty::Const) { self.add_ty(constant.ty); - match constant.val { - ConstVal::Value(_) => {} - ConstVal::Unevaluated(_, substs) => { - self.add_flags(TypeFlags::HAS_PROJECTION); - self.add_substs(substs); - } + if let ConstValue::Unevaluated(_, substs) = constant.val { + self.add_flags(TypeFlags::HAS_PROJECTION); + self.add_substs(substs); } } diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 713aca38df9..f55a5129084 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -39,7 +39,7 @@ //! These methods return true to indicate that the visitor has found what it is looking for //! and does not need to visit anything else. -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use hir::def_id::DefId; use ty::{self, Binder, Ty, TyCtxt, TypeFlags}; @@ -685,7 +685,7 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor { } fn visit_const(&mut self, c: &'tcx ty::Const<'tcx>) -> bool { - if let ConstVal::Unevaluated(..) = c.val { + if let ConstValue::Unevaluated(..) = c.val { let projection_flags = TypeFlags::HAS_NORMALIZABLE_PROJECTION | TypeFlags::HAS_PROJECTION; if projection_flags.intersects(self.flags) { diff --git a/src/librustc/ty/query/config.rs b/src/librustc/ty/query/config.rs index eadfc62244f..229caeb95d6 100644 --- a/src/librustc/ty/query/config.rs +++ b/src/librustc/ty/query/config.rs @@ -11,7 +11,7 @@ use dep_graph::SerializedDepNodeIndex; use dep_graph::DepNode; use hir::def_id::{CrateNum, DefId, DefIndex}; -use mir::interpret::{GlobalId, ConstValue}; +use mir::interpret::GlobalId; use traits::query::{ CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal, CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, @@ -191,8 +191,8 @@ impl<'tcx> QueryDescription<'tcx> for queries::super_predicates_of<'tcx> { } impl<'tcx> QueryDescription<'tcx> for queries::const_value_to_allocation<'tcx> { - fn describe(_tcx: TyCtxt, (val, ty): (ConstValue<'tcx>, Ty<'tcx>)) -> String { - format!("converting value `{:?}` ({}) to an allocation", val, ty) + fn describe(_tcx: TyCtxt, val: &'tcx ty::Const<'tcx>) -> String { + format!("converting value `{:?}` to an allocation", val) } } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index cad3a658682..8423b02ee75 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -145,7 +145,7 @@ impl<'tcx> Key for ty::PolyTraitRef<'tcx>{ } } -impl<'tcx> Key for (mir::interpret::ConstValue<'tcx>, Ty<'tcx>) { +impl<'tcx> Key for &'tcx ty::Const<'tcx> { fn query_crate(&self) -> CrateNum { LOCAL_CRATE } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 1095b943836..77644cdf02b 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -29,7 +29,7 @@ use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol}; use mir::interpret::ConstEvalResult; use mir::mono::{CodegenUnit, Stats}; use mir; -use mir::interpret::{GlobalId, Allocation, ConstValue}; +use mir::interpret::{GlobalId, Allocation}; use session::{CompileResult, CrateDisambiguator}; use session::config::OutputFilenames; use traits::{self, Vtable}; @@ -234,7 +234,7 @@ define_queries! { <'tcx> /// Converts a constant value to an constant allocation [] fn const_value_to_allocation: const_value_to_allocation( - (ConstValue<'tcx>, Ty<'tcx>) + &'tcx ty::Const<'tcx> ) -> &'tcx Allocation, [] fn check_match: CheckMatch(DefId) @@ -570,9 +570,9 @@ fn erase_regions_ty<'tcx>(ty: Ty<'tcx>) -> DepConstructor<'tcx> { } fn const_value_to_allocation<'tcx>( - (val, ty): (ConstValue<'tcx>, Ty<'tcx>) + val: &'tcx ty::Const<'tcx>, ) -> DepConstructor<'tcx> { - DepConstructor::ConstValueToAllocation { val, ty } + DepConstructor::ConstValueToAllocation { val } } fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstructor<'tcx> { diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 407d4c51847..265c6aee397 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -14,7 +14,7 @@ //! type equality, etc. use hir::def_id::DefId; -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use ty::subst::{Kind, UnpackedKind, Substs}; use ty::{self, Ty, TyCtxt, TypeFoldable}; use ty::error::{ExpectedFound, TypeError}; @@ -474,7 +474,7 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, return Ok(s); } match x.val { - ConstVal::Unevaluated(def_id, substs) => { + ConstValue::Unevaluated(def_id, substs) => { // FIXME(eddyb) get the right param_env. let param_env = ty::ParamEnv::empty(); match tcx.lift_to_global(&substs) { diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 254f5b5eb7b..a648dc6e7e7 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -13,7 +13,7 @@ //! hand, though we've recently added some macros (e.g., //! `BraceStructLiftImpl!`) to help with the tedium. -use mir::interpret::{ConstVal, ConstEvalErr}; +use mir::interpret::{ConstValue, ConstEvalErr}; use ty::{self, Lift, Ty, TyCtxt}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use rustc_data_structures::accumulate_vec::AccumulateVec; @@ -1127,20 +1127,24 @@ EnumTypeFoldableImpl! { } } -impl<'tcx> TypeFoldable<'tcx> for ConstVal<'tcx> { +impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match *self { - ConstVal::Value(v) => ConstVal::Value(v), - ConstVal::Unevaluated(def_id, substs) => { - ConstVal::Unevaluated(def_id, substs.fold_with(folder)) + ConstValue::Scalar(v) => ConstValue::Scalar(v), + ConstValue::ScalarPair(a, b) => ConstValue::ScalarPair(a, b), + ConstValue::ByRef(alloc, offset) => ConstValue::ByRef(alloc, offset), + ConstValue::Unevaluated(def_id, substs) => { + ConstValue::Unevaluated(def_id, substs.fold_with(folder)) } } } fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool { match *self { - ConstVal::Value(_) => false, - ConstVal::Unevaluated(_, substs) => substs.visit_with(visitor), + ConstValue::Scalar(_) | + ConstValue::ScalarPair(_, _) | + ConstValue::ByRef(_, _) => false, + ConstValue::Unevaluated(_, substs) => substs.visit_with(visitor), } } } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index e6c2cadc9bb..b9446621eae 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -12,7 +12,7 @@ use hir::def_id::DefId; -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use middle::region; use polonius_engine::Atom; use rustc_data_structures::indexed_vec::Idx; @@ -20,7 +20,7 @@ use ty::subst::{Substs, Subst, Kind, UnpackedKind}; use ty::{self, AdtDef, TypeFlags, Ty, TyCtxt, TypeFoldable}; use ty::{Slice, TyS, ParamEnvAnd, ParamEnv}; use util::captures::Captures; -use mir::interpret::{Scalar, Pointer, Value, ConstValue}; +use mir::interpret::{Scalar, Pointer, Value}; use std::iter; use std::cmp::Ordering; @@ -1859,7 +1859,7 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub struct Const<'tcx> { pub ty: Ty<'tcx>, - pub val: ConstVal<'tcx>, + pub val: ConstValue<'tcx>, } impl<'tcx> Const<'tcx> { @@ -1870,15 +1870,15 @@ impl<'tcx> Const<'tcx> { ty: Ty<'tcx>, ) -> &'tcx Self { tcx.mk_const(Const { - val: ConstVal::Unevaluated(def_id, substs), + val: ConstValue::Unevaluated(def_id, substs), ty, }) } #[inline] - pub fn from_const_val( + pub fn from_const_value( tcx: TyCtxt<'_, '_, 'tcx>, - val: ConstVal<'tcx>, + val: ConstValue<'tcx>, ty: Ty<'tcx>, ) -> &'tcx Self { tcx.mk_const(Const { @@ -1888,15 +1888,6 @@ impl<'tcx> Const<'tcx> { } #[inline] - pub fn from_const_value( - tcx: TyCtxt<'_, '_, 'tcx>, - val: ConstValue<'tcx>, - ty: Ty<'tcx>, - ) -> &'tcx Self { - Self::from_const_val(tcx, ConstVal::Value(val), ty) - } - - #[inline] pub fn from_byval_value( tcx: TyCtxt<'_, '_, 'tcx>, val: Value, @@ -1956,34 +1947,22 @@ impl<'tcx> Const<'tcx> { } let ty = tcx.lift_to_global(&ty).unwrap(); let size = tcx.layout_of(ty).ok()?.size; - match self.val { - ConstVal::Value(val) => val.to_bits(size), - _ => None, - } + self.val.to_bits(size) } #[inline] pub fn to_ptr(&self) -> Option<Pointer> { - match self.val { - ConstVal::Value(val) => val.to_ptr(), - _ => None, - } + self.val.to_ptr() } #[inline] pub fn to_byval_value(&self) -> Option<Value> { - match self.val { - ConstVal::Value(val) => val.to_byval_value(), - _ => None, - } + self.val.to_byval_value() } #[inline] pub fn to_scalar(&self) -> Option<Scalar> { - match self.val { - ConstVal::Value(val) => val.to_scalar(), - _ => None, - } + self.val.to_scalar() } #[inline] @@ -1995,10 +1974,7 @@ impl<'tcx> Const<'tcx> { assert_eq!(self.ty, ty.value); let ty = tcx.lift_to_global(&ty).unwrap(); let size = tcx.layout_of(ty).ok()?.size; - match self.val { - ConstVal::Value(val) => val.to_bits(size), - _ => None, - } + self.val.to_bits(size) } #[inline] diff --git a/src/librustc/ty/walk.rs b/src/librustc/ty/walk.rs index 21cd9affce0..d12f7314426 100644 --- a/src/librustc/ty/walk.rs +++ b/src/librustc/ty/walk.rs @@ -11,7 +11,7 @@ //! An iterator over the type substructure. //! WARNING: this does not keep track of the region depth. -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use ty::{self, Ty}; use rustc_data_structures::small_vec::SmallVec; use rustc_data_structures::accumulate_vec::IntoIter as AccIntoIter; @@ -141,11 +141,8 @@ fn push_subtypes<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent_ty: Ty<'tcx>) { } fn push_const<'tcx>(stack: &mut TypeWalkerStack<'tcx>, constant: &'tcx ty::Const<'tcx>) { - match constant.val { - ConstVal::Value(_) => {} - ConstVal::Unevaluated(_, substs) => { - stack.extend(substs.types().rev()); - } + if let ConstValue::Unevaluated(_, substs) = constant.val { + stack.extend(substs.types().rev()); } stack.push(constant.ty); } diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index d5e5ea527f2..5376acca0d8 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -9,7 +9,7 @@ // except according to those terms. use hir::def_id::DefId; -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use infer::InferCtxt; use ty::subst::Substs; use traits; @@ -216,18 +216,15 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> { /// into `self.out`. fn compute_const(&mut self, constant: &'tcx ty::Const<'tcx>) { self.require_sized(constant.ty, traits::ConstSized); - match constant.val { - ConstVal::Value(_) => {} - ConstVal::Unevaluated(def_id, substs) => { - let obligations = self.nominal_obligations(def_id, substs); - self.out.extend(obligations); - - let predicate = ty::Predicate::ConstEvaluatable(def_id, substs); - let cause = self.cause(traits::MiscObligation); - self.out.push(traits::Obligation::new(cause, - self.param_env, - predicate)); - } + if let ConstValue::Unevaluated(def_id, substs) = constant.val { + let obligations = self.nominal_obligations(def_id, substs); + self.out.extend(obligations); + + let predicate = ty::Predicate::ConstEvaluatable(def_id, substs); + let cause = self.cause(traits::MiscObligation); + self.out.push(traits::Obligation::new(cause, + self.param_env, + predicate)); } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 78bf89cb0d4..343f7298046 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -10,7 +10,7 @@ use hir::def_id::DefId; use hir::map::definitions::DefPathData; -use mir::interpret::ConstVal; +use mir::interpret::ConstValue; use middle::region::{self, BlockRemainder}; use ty::subst::{self, Subst}; use ty::{BrAnon, BrEnv, BrFresh, BrNamed}; @@ -1195,12 +1195,12 @@ define_print! { TyArray(ty, sz) => { print!(f, cx, write("["), print(ty), write("; "))?; match sz.val { - ConstVal::Value(..) => ty::tls::with(|tcx| { - write!(f, "{}", sz.unwrap_usize(tcx)) - })?, - ConstVal::Unevaluated(_def_id, _substs) => { + ConstValue::Unevaluated(_def_id, _substs) => { write!(f, "_")?; } + _ => ty::tls::with(|tcx| { + write!(f, "{}", sz.unwrap_usize(tcx)) + })?, } write!(f, "]") } diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs index 3f0d68f869a..a4709739a23 100644 --- a/src/librustc_codegen_llvm/base.rs +++ b/src/librustc_codegen_llvm/base.rs @@ -1381,7 +1381,6 @@ mod temp_stable_hash_impls { fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) { use rustc::mir::interpret::GlobalId; - use rustc::mir::interpret::ConstVal; info!("loading wasm section {:?}", id); @@ -1399,12 +1398,6 @@ fn fetch_wasm_section(tcx: TyCtxt, id: DefId) -> (String, Vec<u8>) { }; let param_env = ty::ParamEnv::reveal_all(); let val = tcx.const_eval(param_env.and(cid)).unwrap(); - - let const_val = match val.val { - ConstVal::Value(val) => val, - ConstVal::Unevaluated(..) => bug!("should be evaluated"), - }; - - let alloc = tcx.const_value_to_allocation((const_val, val.ty)); + let alloc = tcx.const_value_to_allocation(val); (section.to_string(), alloc.bytes.clone()) } diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs index 3adef1c415a..bbe0e34b48f 100644 --- a/src/librustc_codegen_llvm/mir/constant.rs +++ b/src/librustc_codegen_llvm/mir/constant.rs @@ -9,7 +9,7 @@ // except according to those terms. use llvm::{self, ValueRef}; -use rustc::mir::interpret::{ConstVal, ConstEvalErr}; +use rustc::mir::interpret::ConstEvalErr; use rustc_mir::interpret::{read_target_uint, const_val_field}; use rustc::hir::def_id::DefId; use rustc::mir; @@ -129,20 +129,20 @@ pub fn codegen_static_initializer<'a, 'tcx>( let static_ = cx.tcx.const_eval(param_env.and(cid))?; let alloc = match static_.val { - ConstVal::Value(ConstValue::ByRef(alloc, n)) if n.bytes() == 0 => alloc, + ConstValue::ByRef(alloc, n) if n.bytes() == 0 => alloc, _ => bug!("static const eval returned {:#?}", static_), }; Ok(const_alloc_to_llvm(cx, alloc)) } impl<'a, 'tcx> FunctionCx<'a, 'tcx> { - fn const_to_const_value( + fn fully_evaluate( &mut self, bx: &Builder<'a, 'tcx>, constant: &'tcx ty::Const<'tcx>, - ) -> Result<ConstValue<'tcx>, Lrc<ConstEvalErr<'tcx>>> { + ) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> { match constant.val { - ConstVal::Unevaluated(def_id, ref substs) => { + ConstValue::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(); @@ -150,18 +150,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { instance, promoted: None, }; - let c = tcx.const_eval(param_env.and(cid))?; - self.const_to_const_value(bx, c) + tcx.const_eval(param_env.and(cid)) }, - ConstVal::Value(val) => Ok(val), + _ => Ok(constant), } } - pub fn mir_constant_to_const_value( + pub fn eval_mir_constant( &mut self, bx: &Builder<'a, 'tcx>, constant: &mir::Constant<'tcx>, - ) -> Result<ConstValue<'tcx>, Lrc<ConstEvalErr<'tcx>>> { + ) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> { match constant.literal { mir::Literal::Promoted { index } => { let param_env = ty::ParamEnv::reveal_all(); @@ -174,7 +173,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { mir::Literal::Value { value } => { Ok(self.monomorphize(&value)) } - }.and_then(|c| self.const_to_const_value(bx, c)) + }.and_then(|c| self.fully_evaluate(bx, c)) } /// process constant containing SIMD shuffle indices @@ -183,10 +182,10 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { bx: &Builder<'a, 'tcx>, constant: &mir::Constant<'tcx>, ) -> (ValueRef, Ty<'tcx>) { - self.mir_constant_to_const_value(bx, constant) + self.eval_mir_constant(bx, constant) .and_then(|c| { - let field_ty = constant.ty.builtin_index().unwrap(); - let fields = match constant.ty.sty { + let field_ty = c.ty.builtin_index().unwrap(); + let fields = match c.ty.sty { ty::TyArray(_, n) => n.unwrap_usize(bx.tcx()), ref other => bug!("invalid simd shuffle type: {}", other), }; @@ -198,7 +197,6 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { None, mir::Field::new(field as usize), c, - constant.ty, )?; if let Some(prim) = field.to_scalar() { let layout = bx.cx.layout_of(field_ty); @@ -215,7 +213,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } }).collect(); let llval = C_struct(bx.cx, &values?, false); - Ok((llval, constant.ty)) + Ok((llval, c.ty)) }) .unwrap_or_else(|e| { e.report_as_error( diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs index 21b67b2c388..3d3a4400bd8 100644 --- a/src/librustc_codegen_llvm/mir/operand.rs +++ b/src/librustc_codegen_llvm/mir/operand.rs @@ -96,16 +96,16 @@ impl<'a, 'tcx> OperandRef<'tcx> { } pub fn from_const(bx: &Builder<'a, 'tcx>, - val: ConstValue<'tcx>, - ty: ty::Ty<'tcx>) + val: &'tcx ty::Const<'tcx>) -> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> { - let layout = bx.cx.layout_of(ty); + let layout = bx.cx.layout_of(val.ty); if layout.is_zst() { return Ok(OperandRef::new_zst(bx.cx, layout)); } - let val = match val { + let val = match val.val { + ConstValue::Unevaluated(..) => bug!(), ConstValue::Scalar(x) => { let scalar = match layout.abi { layout::Abi::Scalar(ref x) => x, @@ -409,8 +409,8 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { mir::Operand::Constant(ref constant) => { let ty = self.monomorphize(&constant.ty); - self.mir_constant_to_const_value(bx, constant) - .and_then(|c| OperandRef::from_const(bx, c, ty)) + self.eval_mir_constant(bx, constant) + .and_then(|c| OperandRef::from_const(bx, c)) .unwrap_or_else(|err| { match constant.literal { mir::Literal::Promoted { .. } => { diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index c04a011cb02..83361ea57c3 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -12,8 +12,6 @@ use self::Constructor::*; use self::Usefulness::*; use self::WitnessPreference::*; -use rustc::mir::interpret::ConstVal; - use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::Idx; @@ -544,14 +542,9 @@ fn max_slice_length<'p, 'a: 'p, 'tcx: 'a, I>( for row in patterns { match *row.kind { - PatternKind::Constant { - value: const_val @ &ty::Const { - val: ConstVal::Value(..), - .. - } - } => { - if let Some(ptr) = const_val.to_ptr() { - let is_array_ptr = const_val.ty + PatternKind::Constant { value } => { + if let Some(ptr) = value.to_ptr() { + let is_array_ptr = value.ty .builtin_deref(true) .and_then(|t| t.ty.builtin_index()) .map_or(false, |t| t == cx.tcx.types.u8); @@ -933,13 +926,14 @@ fn slice_pat_covered_by_constructor<'tcx>( suffix: &[Pattern<'tcx>] ) -> Result<bool, ErrorReported> { let data: &[u8] = match *ctor { - ConstantValue(&ty::Const { val: ConstVal::Value(const_val), ty }) => { - let val = match const_val { - ConstValue::ByRef(..) => bug!("unexpected ConstValue::ByRef"), + ConstantValue(const_val) => { + let val = match const_val.val { + ConstValue::Unevaluated(..) | + ConstValue::ByRef(..) => bug!("unexpected ConstValue: {:?}", const_val), ConstValue::Scalar(val) | ConstValue::ScalarPair(val, _) => val, }; if let Ok(ptr) = val.to_ptr() { - let is_array_ptr = ty + let is_array_ptr = const_val.ty .builtin_deref(true) .and_then(|t| t.ty.builtin_index()) .map_or(false, |t| t == tcx.types.u8); diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index e66539b3e5f..6e736e9284e 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -18,7 +18,6 @@ pub(crate) use self::check_match::check_match; use interpret::{const_val_field, const_variant_index, self}; -use rustc::mir::interpret::ConstVal; use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, Value}; use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region}; @@ -122,13 +121,6 @@ pub enum PatternKind<'tcx> { }, } -fn print_const_val(value: &ty::Const, f: &mut fmt::Formatter) -> fmt::Result { - match value.val { - ConstVal::Value(..) => fmt_const_val(f, value), - ConstVal::Unevaluated(..) => bug!("{:?} not printable in a pattern", value) - } -} - impl<'tcx> fmt::Display for Pattern<'tcx> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self.kind { @@ -236,15 +228,15 @@ impl<'tcx> fmt::Display for Pattern<'tcx> { write!(f, "{}", subpattern) } PatternKind::Constant { value } => { - print_const_val(value, f) + fmt_const_val(f, value) } PatternKind::Range { lo, hi, end } => { - print_const_val(lo, f)?; + fmt_const_val(f, lo)?; match end { RangeEnd::Included => write!(f, "...")?, RangeEnd::Excluded => write!(f, "..")?, } - print_const_val(hi, f) + fmt_const_val(f, hi) } PatternKind::Slice { ref prefix, ref slice, ref suffix } | PatternKind::Array { ref prefix, ref slice, ref suffix } => { @@ -795,13 +787,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { debug!("const_to_pat: cv={:#?}", cv); let adt_subpattern = |i, variant_opt| { let field = Field::new(i); - let val = match cv.val { - ConstVal::Value(miri) => const_val_field( - self.tcx, self.param_env, instance, - variant_opt, field, miri, cv.ty, - ).expect("field access failed"), - _ => bug!("{:#?} is not a valid adt", cv), - }; + let val = const_val_field( + self.tcx, self.param_env, instance, + variant_opt, field, cv, + ).expect("field access failed"); self.const_to_pat(instance, val, id, span) }; let adt_subpatterns = |n, variant_opt| { @@ -840,24 +829,18 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { PatternKind::Wild }, ty::TyAdt(adt_def, substs) if adt_def.is_enum() => { - match cv.val { - ConstVal::Value(val) => { - let variant_index = const_variant_index( - self.tcx, self.param_env, instance, val, cv.ty - ).expect("const_variant_index failed"); - let subpatterns = adt_subpatterns( - adt_def.variants[variant_index].fields.len(), - Some(variant_index), - ); - PatternKind::Variant { - adt_def, - substs, - variant_index, - subpatterns, - } - }, - ConstVal::Unevaluated(..) => - span_bug!(span, "{:#?} is not a valid enum constant", cv), + let variant_index = const_variant_index( + self.tcx, self.param_env, instance, cv + ).expect("const_variant_index failed"); + let subpatterns = adt_subpatterns( + adt_def.variants[variant_index].fields.len(), + Some(variant_index), + ); + PatternKind::Variant { + adt_def, + substs, + variant_index, + subpatterns, } }, ty::TyAdt(adt_def, _) => { diff --git a/src/librustc_mir/interpret/const_eval.rs b/src/librustc_mir/interpret/const_eval.rs index 57a703c783f..35422b11bd7 100644 --- a/src/librustc_mir/interpret/const_eval.rs +++ b/src/librustc_mir/interpret/const_eval.rs @@ -425,13 +425,13 @@ pub fn const_val_field<'a, 'tcx>( instance: ty::Instance<'tcx>, variant: Option<usize>, field: mir::Field, - value: ConstValue<'tcx>, - ty: Ty<'tcx>, + value: &'tcx ty::Const<'tcx>, ) -> ::rustc::mir::interpret::ConstEvalResult<'tcx> { - trace!("const_val_field: {:?}, {:?}, {:?}, {:?}", instance, field, value, ty); + trace!("const_val_field: {:?}, {:?}, {:?}", instance, field, value); let mut ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); let result = (|| { - let value = ecx.const_value_to_value(value, ty)?; + let ty = value.ty; + let value = ecx.const_to_value(value.val)?; let layout = ecx.layout_of(ty)?; let (ptr, align) = match value { Value::ByRef(ptr, align) => (ptr, align), @@ -478,30 +478,29 @@ pub fn const_variant_index<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, param_env: ty::ParamEnv<'tcx>, instance: ty::Instance<'tcx>, - val: ConstValue<'tcx>, - ty: Ty<'tcx>, + val: &'tcx ty::Const<'tcx>, ) -> EvalResult<'tcx, usize> { - trace!("const_variant_index: {:?}, {:?}, {:?}", instance, val, ty); + trace!("const_variant_index: {:?}, {:?}", instance, val); let mut ecx = mk_eval_cx(tcx, instance, param_env).unwrap(); - let value = ecx.const_value_to_value(val, ty)?; + let value = ecx.const_to_value(val.val)?; let (ptr, align) = match value { Value::ScalarPair(..) | Value::Scalar(_) => { - let layout = ecx.layout_of(ty)?; + let layout = ecx.layout_of(val.ty)?; let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?.into(); - ecx.write_value_to_ptr(value, ptr, layout.align, ty)?; + ecx.write_value_to_ptr(value, ptr, layout.align, val.ty)?; (ptr, layout.align) }, Value::ByRef(ptr, align) => (ptr, align), }; let place = Place::from_scalar_ptr(ptr, align); - ecx.read_discriminant_as_variant_index(place, ty) + ecx.read_discriminant_as_variant_index(place, val.ty) } pub fn const_value_to_allocation_provider<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, - (val, ty): (ConstValue<'tcx>, Ty<'tcx>), + val: &'tcx ty::Const<'tcx>, ) -> &'tcx Allocation { - match val { + match val.val { ConstValue::ByRef(alloc, offset) => { assert_eq!(offset.bytes(), 0); return alloc; @@ -514,14 +513,14 @@ pub fn const_value_to_allocation_provider<'a, 'tcx>( ty::ParamEnv::reveal_all(), CompileTimeEvaluator, ()); - let value = ecx.const_value_to_value(val, ty)?; - let layout = ecx.layout_of(ty)?; + let value = ecx.const_to_value(val.val)?; + let layout = ecx.layout_of(val.ty)?; let ptr = ecx.memory.allocate(layout.size, layout.align, Some(MemoryKind::Stack))?; - ecx.write_value_to_ptr(value, ptr.into(), layout.align, ty)?; + ecx.write_value_to_ptr(value, ptr.into(), layout.align, val.ty)?; let alloc = ecx.memory.get(ptr.alloc_id)?; Ok(tcx.intern_const_alloc(alloc.clone())) }; - result().expect("unable to convert ConstVal to Allocation") + result().expect("unable to convert ConstValue to Allocation") } pub fn const_eval_provider<'a, 'tcx>( diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b3ec2459b05..6dc65a2404d 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -3,7 +3,6 @@ use std::fmt::Write; use rustc::hir::def_id::DefId; use rustc::hir::def::Def; use rustc::hir::map::definitions::DefPathData; -use rustc::mir::interpret::ConstVal; use rustc::mir; use rustc::ty::layout::{self, Size, Align, HasDataLayout, IntegerExt, LayoutOf, TyLayout}; use rustc::ty::subst::{Subst, Substs}; @@ -233,12 +232,18 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M Ok(Scalar::Ptr(ptr).to_value_with_len(s.len() as u64, self.tcx.tcx)) } - pub fn const_value_to_value( + pub fn const_to_value( &mut self, val: ConstValue<'tcx>, - _ty: Ty<'tcx>, ) -> EvalResult<'tcx, Value> { match val { + ConstValue::Unevaluated(def_id, substs) => { + let instance = self.resolve(def_id, substs)?; + self.read_global_as_value(GlobalId { + instance, + promoted: None, + }) + } ConstValue::ByRef(alloc, offset) => { // FIXME: Allocate new AllocId for all constants inside let id = self.memory.allocate_value(alloc.clone(), Some(MemoryKind::Stack))?; @@ -249,23 +254,6 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M } } - pub(super) fn const_to_value( - &mut self, - const_val: &ConstVal<'tcx>, - ty: Ty<'tcx> - ) -> EvalResult<'tcx, Value> { - match *const_val { - ConstVal::Unevaluated(def_id, substs) => { - let instance = self.resolve(def_id, substs)?; - self.read_global_as_value(GlobalId { - instance, - promoted: None, - }, ty) - } - ConstVal::Value(val) => self.const_value_to_value(val, ty) - } - } - pub(super) fn resolve(&self, def_id: DefId, substs: &'tcx Substs<'tcx>) -> EvalResult<'tcx, ty::Instance<'tcx>> { trace!("resolve: {:?}, {:#?}", def_id, substs); trace!("substs: {:#?}", self.substs()); @@ -849,14 +837,14 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M use rustc::mir::Literal; let mir::Constant { ref literal, .. } = **constant; let value = match *literal { - Literal::Value { ref value } => self.const_to_value(&value.val, ty)?, + Literal::Value { ref value } => self.const_to_value(value.val)?, Literal::Promoted { index } => { let instance = self.frame().instance; self.read_global_as_value(GlobalId { instance, promoted: Some(index), - }, ty)? + })? } }; @@ -1036,18 +1024,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M Ok(()) } - pub fn read_global_as_value(&mut self, gid: GlobalId<'tcx>, ty: Ty<'tcx>) -> EvalResult<'tcx, Value> { - if self.tcx.is_static(gid.instance.def_id()).is_some() { - let alloc_id = self - .tcx - .alloc_map - .lock() - .intern_static(gid.instance.def_id()); - let layout = self.layout_of(ty)?; - return Ok(Value::ByRef(Scalar::Ptr(alloc_id.into()), layout.align)) - } + pub fn read_global_as_value(&mut self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, Value> { let cv = self.const_eval(gid)?; - self.const_to_value(&cv.val, ty) + self.const_to_value(cv.val) } pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> { diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 1d4df97ce76..9e5b6be3e91 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -7,7 +7,6 @@ use rustc::ty::ParamEnv; use rustc::ty::query::TyCtxtAt; use rustc::ty::layout::{self, Align, TargetDataLayout, Size}; use syntax::ast::Mutability; -use rustc::mir::interpret::ConstVal; use rustc_data_structures::fx::{FxHashSet, FxHashMap}; use rustc::mir::interpret::{Pointer, AllocId, Allocation, AccessKind, Value, @@ -290,11 +289,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> { assert!(self.tcx.is_static(def_id).is_some()); EvalErrorKind::ReferencedConstant(err).into() }).map(|val| { - let const_val = match val.val { - ConstVal::Value(val) => val, - ConstVal::Unevaluated(..) => bug!("should be evaluated"), - }; - self.tcx.const_value_to_allocation((const_val, val.ty)) + self.tcx.const_value_to_allocation(val) }) } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 59af0478073..744c65a05a7 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -193,7 +193,6 @@ use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::hir::map as hir_map; use rustc::hir::def_id::DefId; -use rustc::mir::interpret::ConstVal; use rustc::mir::interpret::{AllocId, ConstValue}; use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem}; use rustc::ty::subst::Substs; @@ -1239,7 +1238,7 @@ fn collect_const<'a, 'tcx>( debug!("visiting const {:?}", *constant); let val = match constant.val { - ConstVal::Unevaluated(def_id, substs) => { + ConstValue::Unevaluated(def_id, substs) => { let param_env = ty::ParamEnv::reveal_all(); let substs = tcx.subst_and_normalize_erasing_regions( param_substs, @@ -1270,16 +1269,16 @@ fn collect_const<'a, 'tcx>( _ => constant.val, }; match val { - ConstVal::Unevaluated(..) => bug!("const eval yielded unevaluated const"), - ConstVal::Value(ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b))) => { + ConstValue::Unevaluated(..) => bug!("const eval yielded unevaluated const"), + ConstValue::ScalarPair(Scalar::Ptr(a), Scalar::Ptr(b)) => { collect_miri(tcx, a.alloc_id, output); collect_miri(tcx, b.alloc_id, output); } - ConstVal::Value(ConstValue::ScalarPair(_, Scalar::Ptr(ptr))) | - ConstVal::Value(ConstValue::ScalarPair(Scalar::Ptr(ptr), _)) | - ConstVal::Value(ConstValue::Scalar(Scalar::Ptr(ptr))) => + ConstValue::ScalarPair(_, Scalar::Ptr(ptr)) | + ConstValue::ScalarPair(Scalar::Ptr(ptr), _) | + ConstValue::Scalar(Scalar::Ptr(ptr)) => collect_miri(tcx, ptr.alloc_id, output), - ConstVal::Value(ConstValue::ByRef(alloc, _offset)) => { + ConstValue::ByRef(alloc, _offset) => { for &id in alloc.relocations.values() { collect_miri(tcx, id, output); } diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 38b9ae3c3ce..649309c4eb4 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -17,7 +17,7 @@ use rustc::mir::{Constant, Literal, Location, Place, Mir, Operand, Rvalue, Local use rustc::mir::{NullOp, StatementKind, Statement, BasicBlock, LocalKind}; use rustc::mir::{TerminatorKind, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem}; use rustc::mir::visit::{Visitor, PlaceContext}; -use rustc::mir::interpret::{ConstVal, ConstEvalErr}; +use rustc::mir::interpret::ConstEvalErr; use rustc::ty::{TyCtxt, self, Instance}; use rustc::mir::interpret::{Value, Scalar, GlobalId, EvalResult}; use interpret::EvalContext; @@ -160,54 +160,17 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> { r } - fn const_eval(&mut self, cid: GlobalId<'tcx>, source_info: SourceInfo) -> Option<Const<'tcx>> { - let value = match self.tcx.const_eval(self.param_env.and(cid)) { - Ok(val) => val, - Err(err) => { - err.report_as_error( - self.tcx.at(err.span), - "constant evaluation error", - ); - return None; - }, - }; - let val = match value.val { - ConstVal::Value(v) => { - self.use_ecx(source_info, |this| this.ecx.const_value_to_value(v, value.ty))? - }, - _ => bug!("eval produced: {:?}", value), - }; - let val = (val, value.ty, source_info.span); - trace!("evaluated {:?} to {:?}", cid, val); - Some(val) - } - fn eval_constant( &mut self, c: &Constant<'tcx>, source_info: SourceInfo, ) -> Option<Const<'tcx>> { match c.literal { - Literal::Value { value } => match value.val { - ConstVal::Value(v) => { - let v = self.use_ecx(source_info, |this| { - this.ecx.const_value_to_value(v, value.ty) - })?; - Some((v, value.ty, c.span)) - }, - ConstVal::Unevaluated(did, substs) => { - let instance = Instance::resolve( - self.tcx, - self.param_env, - did, - substs, - )?; - let cid = GlobalId { - instance, - promoted: None, - }; - self.const_eval(cid, source_info) - }, + Literal::Value { value } => { + let v = self.use_ecx(source_info, |this| { + this.ecx.const_to_value(value.val) + })?; + Some((v, value.ty, c.span)) }, // evaluate the promoted and replace the constant with the evaluated result Literal::Promoted { index } => { diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index c897e9dc1f6..144ebce76e1 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -20,7 +20,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx}; use rustc_data_structures::fx::FxHashSet; use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::mir::interpret::ConstVal; +use rustc::mir::interpret::ConstValue; use rustc::traits::{self, TraitEngine}; use rustc::ty::{self, TyCtxt, Ty, TypeFoldable}; use rustc::ty::cast::CastTy; @@ -611,7 +611,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } Operand::Constant(ref constant) => { if let Literal::Value { - value: &ty::Const { val: ConstVal::Unevaluated(def_id, _), ty, .. } + value: &ty::Const { val: ConstValue::Unevaluated(def_id, _), ty, .. } } = constant.literal { // Don't peek inside trait associated constants. if self.tcx.trait_of_item(def_id).is_some() { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 3cd434e08fa..4d7fc7fb1c4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -29,7 +29,7 @@ use syntax::symbol::keywords::{self, Keyword}; use syntax::symbol::{Symbol, InternedString}; use syntax_pos::{self, DUMMY_SP, Pos, FileName}; -use rustc::mir::interpret::ConstVal; +use rustc::mir::interpret::ConstValue; use rustc::middle::privacy::AccessLevels; use rustc::middle::resolve_lifetime as rl; use rustc::ty::fold::TypeFolder; @@ -3014,7 +3014,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> { ty::TySlice(ty) => Slice(box ty.clean(cx)), ty::TyArray(ty, n) => { let mut n = cx.tcx.lift(&n).unwrap(); - if let ConstVal::Unevaluated(def_id, substs) = n.val { + 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), @@ -4096,14 +4096,14 @@ fn name_from_pat(p: &hir::Pat) -> String { fn print_const(cx: &DocContext, n: &ty::Const) -> String { match n.val { - ConstVal::Unevaluated(def_id, _) => { + ConstValue::Unevaluated(def_id, _) => { if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) { print_const_expr(cx, cx.tcx.hir.body_owned_by(node_id)) } else { inline::print_inlined_const(cx, def_id) } }, - ConstVal::Value(..) => { + _ => { let mut s = String::new(); ::rustc::mir::fmt_const_val(&mut s, n).unwrap(); // array lengths are obviously usize diff --git a/src/test/compile-fail/const-err-multi.rs b/src/test/compile-fail/const-err-multi.rs index 4a5e78b381e..9405b4134bc 100644 --- a/src/test/compile-fail/const-err-multi.rs +++ b/src/test/compile-fail/const-err-multi.rs @@ -11,19 +11,24 @@ #![deny(const_err)] pub const A: i8 = -std::i8::MIN; -//~^ ERROR E0080 -//~| ERROR attempt to negate with overflow +//~^ ERROR attempt to negate with overflow //~| ERROR this expression will panic at runtime //~| ERROR this constant cannot be used pub const B: i8 = A; //~^ ERROR const_err //~| ERROR const_err +//~| ERROR const_err +//~| ERROR const_err pub const C: u8 = A as u8; //~^ ERROR const_err //~| ERROR const_err +//~| ERROR const_err +//~| ERROR const_err pub const D: i8 = 50 - A; //~^ ERROR const_err //~| ERROR const_err +//~| ERROR const_err +//~| ERROR const_err fn main() { let _ = (A, B, C, D); diff --git a/src/test/compile-fail/const-err.rs b/src/test/compile-fail/const-err.rs index f77603b3eba..f6a64bcba21 100644 --- a/src/test/compile-fail/const-err.rs +++ b/src/test/compile-fail/const-err.rs @@ -23,7 +23,6 @@ fn black_box<T>(_: T) { // Make sure that the two uses get two errors. const FOO: u8 = [5u8][1]; //~^ ERROR constant evaluation error -//~| ERROR constant evaluation error //~| index out of bounds: the len is 1 but the index is 1 fn main() { diff --git a/src/test/ui/const-len-underflow-separate-spans.rs b/src/test/ui/const-len-underflow-separate-spans.rs index 20b88657674..3d299988a96 100644 --- a/src/test/ui/const-len-underflow-separate-spans.rs +++ b/src/test/ui/const-len-underflow-separate-spans.rs @@ -15,11 +15,12 @@ const ONE: usize = 1; const TWO: usize = 2; const LEN: usize = ONE - TWO; -//~^ ERROR E0080 -//~| ERROR attempt to subtract with overflow +//~^ ERROR attempt to subtract with overflow fn main() { let a: [i8; LEN] = unimplemented!(); //~^ ERROR E0080 //~| ERROR E0080 +//~| ERROR const_err +//~| ERROR const_err } diff --git a/src/test/ui/const-len-underflow-separate-spans.stderr b/src/test/ui/const-len-underflow-separate-spans.stderr index 630828ef8f5..cc851624e0e 100644 --- a/src/test/ui/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/const-len-underflow-separate-spans.stderr @@ -6,14 +6,23 @@ LL | const LEN: usize = ONE - TWO; | = note: #[deny(const_err)] on by default -error[E0080]: constant evaluation error - --> $DIR/const-len-underflow-separate-spans.rs:17:20 +error: referenced constant + --> $DIR/const-len-underflow-separate-spans.rs:21:17 | LL | const LEN: usize = ONE - TWO; - | ^^^^^^^^^ attempt to subtract with overflow + | --------- attempt to subtract with overflow +... +LL | let a: [i8; LEN] = unimplemented!(); + | ^^^ + +error: this expression will panic at runtime + --> $DIR/const-len-underflow-separate-spans.rs:21:17 + | +LL | let a: [i8; LEN] = unimplemented!(); + | ^^^ referenced constant has errors error[E0080]: referenced constant - --> $DIR/const-len-underflow-separate-spans.rs:22:12 + --> $DIR/const-len-underflow-separate-spans.rs:21:12 | LL | const LEN: usize = ONE - TWO; | --------- attempt to subtract with overflow @@ -22,13 +31,13 @@ LL | let a: [i8; LEN] = unimplemented!(); | ^^^^^^^^^ error[E0080]: could not evaluate constant expression - --> $DIR/const-len-underflow-separate-spans.rs:22:12 + --> $DIR/const-len-underflow-separate-spans.rs:21:12 | LL | let a: [i8; LEN] = unimplemented!(); | ^^^^^---^ | | | referenced constant has errors -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0080`. |
