]> git.lizzy.rs Git - rust.git/commitdiff
Merge `ConstVal` and `ConstValue`
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Mon, 25 Jun 2018 18:53:02 +0000 (20:53 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Thu, 28 Jun 2018 09:04:25 +0000 (11:04 +0200)
35 files changed:
src/librustc/dep_graph/dep_node.rs
src/librustc/ich/impls_ty.rs
src/librustc/mir/interpret/error.rs
src/librustc/mir/interpret/mod.rs
src/librustc/mir/interpret/value.rs
src/librustc/mir/mod.rs
src/librustc/traits/project.rs
src/librustc/traits/query/normalize.rs
src/librustc/ty/flags.rs
src/librustc/ty/fold.rs
src/librustc/ty/query/config.rs
src/librustc/ty/query/keys.rs
src/librustc/ty/query/mod.rs
src/librustc/ty/relate.rs
src/librustc/ty/structural_impls.rs
src/librustc/ty/sty.rs
src/librustc/ty/walk.rs
src/librustc/ty/wf.rs
src/librustc/util/ppaux.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/mir/constant.rs
src/librustc_codegen_llvm/mir/operand.rs
src/librustc_mir/hair/pattern/_match.rs
src/librustc_mir/hair/pattern/mod.rs
src/librustc_mir/interpret/const_eval.rs
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/memory.rs
src/librustc_mir/monomorphize/collector.rs
src/librustc_mir/transform/const_prop.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustdoc/clean/mod.rs
src/test/compile-fail/const-err-multi.rs
src/test/compile-fail/const-err.rs
src/test/ui/const-len-underflow-separate-spans.rs
src/test/ui/const-len-underflow-separate-spans.stderr

index 33322993b1db6289be3317638f9743e252387aec..6cc61d748001a191f9bf4428080f1881dc2f285e 100644 (file)
@@ -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 @@
     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 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
     // 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),
index d3280a9130ea9a0aa7cfb93cb38c53b294d7541f..4eb677732c2a2d66378b5eea581904ff29ac9377 100644 (file)
@@ -370,11 +370,11 @@ fn hash_stable<W: StableHasherResult>(&self,
 }
 
 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 @@ fn hash_stable<W: StableHasherResult>(&self,
                 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);
             }
index dca1c12b51df19a6303433c75c8341734f55b057..3291d6bf1521f43b6a81bde9701be78a022effb4 100644 (file)
 
 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;
 
 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,
index bd8970f5ea69c3aa1ee20ba0a0f8f4351abf63bf..018c2446054be5080f2870d1804f3a32be31d171 100644 (file)
@@ -9,7 +9,7 @@ macro_rules! err {
 mod value;
 
 pub use self::error::{
-    EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstVal, ConstEvalErr, struct_error,
+    EvalError, EvalResult, EvalErrorKind, AssertMessage, ConstEvalErr, struct_error,
     FrameInfo, ConstEvalResult,
 };
 
index 9e3d4e60603ec8f6173dd8b8e9a6e3db7ff26b29..24595c9328208a2a1183e1b11baad07ec9f11f17 100644 (file)
@@ -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 @@ pub fn from_byval_value(val: Value) -> Self {
     #[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 @@ pub fn from_scalar(val: Scalar) -> Self {
     #[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),
         }
index 31d5ef2e16036998bacb6b82a103127f80844517..2198e3f6b318ef1c60f2f4af577a818eff50bd41 100644 (file)
@@ -2162,18 +2162,12 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
     }
 }
 
-/// 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)
     }
 }
 
index 73d288761a0ce7f27b415c32658406d59a5fe557..c49bcbf8f03163ed828571cda76cb25fdac8e618 100644 (file)
@@ -28,7 +28,7 @@
 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 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'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.selcx.tcx().global_tcx();
             if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
                 if substs.needs_infer() || substs.has_skol() {
index c33f028ae1e48076ba9240add14571d6da7bf894..bc2f1b7f6c7c8e13cc8f29479dff2df72ca0a8f6 100644 (file)
@@ -194,7 +194,7 @@ fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'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() {
index 3c798648e19af09dbf95ccf04963ed7e4fe25e1e..3718c436b3a0019fa5d42321449c0b1debabf39c 100644 (file)
@@ -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 @@ fn add_region(&mut self, r: ty::Region) {
 
     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);
         }
     }
 
index 713aca38df9ecdb92180f83e7b2a705e5bf3feaa..f55a512908499a4b7817bea0b576ec1414d8dabc 100644 (file)
@@ -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 @@ fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
     }
 
     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) {
index eadfc62244f815179f55b9264eb0f21c99b50099..229caeb95d62105d77a15051c6edacfeac18ef2e 100644 (file)
@@ -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 @@ fn describe(tcx: TyCtxt, def_id: DefId) -> String {
 }
 
 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)
     }
 }
 
index cad3a6586829e0d348142fe3ea3d14eb259eb34f..8423b02ee7582d2e73f74f30ba285592aeffba3b 100644 (file)
@@ -145,7 +145,7 @@ fn default_span(&self, tcx: TyCtxt) -> Span {
     }
 }
 
-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
     }
index 1095b943836ec76d5d7fb0d40b5e83db9adf450a..77644cdf02b116d63e173a9d5c9f97916da3941c 100644 (file)
@@ -29,7 +29,7 @@
 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};
 
     /// 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> {
index 407d4c51847b99e7efab2b9b4706263a8e26f25e..265c6aee397266a298e134c19063f4b7719db234 100644 (file)
@@ -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) {
index 254f5b5eb7bb5cf0543d4ea471b164f356ff7518..a648dc6e7e7880a166b002760c3b6d4604c2ee2b 100644 (file)
@@ -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 @@ impl<'tcx> TypeFoldable<'tcx> for ty::error::TypeError<'tcx> {
     }
 }
 
-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),
         }
     }
 }
index e6c2cadc9bb4fe0e1f4ee02e2bdf232eb3cb99f2..b9446621eae6ca7a7ce14eb63fbca0fc83e623af 100644 (file)
@@ -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::{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 @@ pub fn to_opt_closure_kind(&self) -> Option<ty::ClosureKind> {
 pub struct Const<'tcx> {
     pub ty: Ty<'tcx>,
 
-    pub val: ConstVal<'tcx>,
+    pub val: ConstValue<'tcx>,
 }
 
 impl<'tcx> Const<'tcx> {
@@ -1870,15 +1870,15 @@ pub fn unevaluated(
         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 {
@@ -1887,15 +1887,6 @@ pub fn from_const_val(
         })
     }
 
-    #[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>,
@@ -1956,34 +1947,22 @@ pub fn to_bits(
         }
         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 @@ pub fn assert_bits(
         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]
index 21cd9affce0a21f7fb9bbd2489278687e4a1f6b2..d12f73144269bf7e87676fb038526149b34d2008 100644 (file)
@@ -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);
 }
index d5e5ea527f255fd675062b09db3178cb64cdd412..5376acca0d8cdabf5402fc13631a2731f63abfb9 100644 (file)
@@ -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 @@ fn compute_projection(&mut self, data: ty::ProjectionTy<'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));
         }
     }
 
index 78bf89cb0d41ae845fcc076c8e499299d5c90b20..343f72980463102753029e4a6c03864441b11cbf 100644 (file)
@@ -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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 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, "]")
                 }
index 3f0d68f869a6a9a87389d76bcd8c4930ff16b8cd..a4709739a23ddabcbb587813975a407d82fe9af3 100644 (file)
@@ -1381,7 +1381,6 @@ fn hash_stable<W: StableHasherResult>(&self,
 
 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())
 }
index 3adef1c415ada2ad20f5206e2b0ac48268622bd5..bbe0e34b48f2642bb1754c9b801b7c17de0250d2 100644 (file)
@@ -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 @@ fn const_to_const_value(
                     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 @@ pub fn mir_constant_to_const_value(
             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 @@ pub fn simd_shuffle_indices(
         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 @@ pub fn simd_shuffle_indices(
                         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 @@ pub fn simd_shuffle_indices(
                     }
                 }).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(
index 21b67b2c3888fd0d44c2d4a9976429af25a1e268..3d3a4400bd8108abca11973e5693f839dbc5fc32 100644 (file)
@@ -96,16 +96,16 @@ pub fn new_zst(cx: &CodegenCx<'a, '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 @@ pub fn codegen_operand(&mut self,
 
             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 { .. } => {
index c04a011cb02f49badeaff50c46af8b872814191b..83361ea57c371e49aac538747b06130ed0351874 100644 (file)
@@ -12,8 +12,6 @@
 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);
index e66539b3e5f727bbcc240365ff7242eccba7ecaf..6e736e9284ee37e567c9e68f0a8165bb5b6f5a9e 100644 (file)
@@ -18,7 +18,6 @@
 
 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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 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 @@ fn const_to_pat(
         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 @@ fn const_to_pat(
                 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, _) => {
index 57a703c783f7960897359a73f37b29357359f166..35422b11bd733714524b7aa9c24289079b654a0c 100644 (file)
@@ -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>(
index b3ec2459b05efc16eeab70e5eba61cf5b05e77d6..6dc65a2404d11ab9d0c947ffb05181856cbcffe4 100644 (file)
@@ -3,7 +3,6 @@
 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 @@ pub fn str_to_value(&mut self, s: &str) -> EvalResult<'tcx, Value> {
         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 @@ pub fn const_value_to_value(
         }
     }
 
-    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 @@ pub fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, ValT
                 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 @@ pub fn write_discriminant_value(
         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>> {
index 1d4df97ce76ca30d7329e9a0a2df60d225690bec..9e5b6be3e9122eff1ff95d39bcf8e458002e7fb6 100644 (file)
@@ -7,7 +7,6 @@
 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 @@ fn const_eval_static(&self, def_id: DefId) -> EvalResult<'tcx, &'tcx Allocation>
             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)
         })
     }
 
index 59af0478073a576a7cc41bdef7d825381bc878d3..744c65a05a71660151f1029d0dc3205a55d6a800 100644 (file)
 
 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);
             }
index 38b9ae3c3cec31018a149e6242fdecf2f984dfd6..649309c4eb4ff6eadb2274ea2b3ac94879d08587 100644 (file)
@@ -17,7 +17,7 @@
 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 @@ fn use_ecx<F, T>(
         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 } => {
index c897e9dc1f6bc58c1f835e4642c195ad078bd5c4..144ebce76e14cbe01f5137a041c4d77249ae76c1 100644 (file)
@@ -20,7 +20,7 @@
 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 @@ fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
             }
             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() {
index 3cd434e08fa352a74f00c8484b8833b243a4ecf3..4d7fc7fb1c4878568ea3049545062f0fb9e4bb1e 100644 (file)
@@ -29,7 +29,7 @@
 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 @@ fn clean(&self, cx: &DocContext) -> Type {
             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
index 4a5e78b381ed049bdace21dc842ded1f758f6ed9..9405b4134bcaafaa54283efe97bd5860fb5e8a1f 100644 (file)
 #![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);
index f77603b3ebafcf83a884e12316dec5e278220fd5..f6a64bcba21c3a6b15f0ce0eeafa3dacc49350d0 100644 (file)
@@ -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() {
index 20b8865767459793351b132fe896878a2543496c..3d299988a960c97c996343ea77f3afdc127c2566 100644 (file)
 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
 }
index 630828ef8f5178adbacc2bc7a9b4d55c4069e824..cc851624e0e68a4194b2db1c5a43c843fcc4dd32 100644 (file)
@@ -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`.