about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-11-06 16:16:27 +0100
committerRalf Jung <post@ralfj.de>2018-11-19 22:42:46 +0100
commitba82f54b04f429d29b0d7c5aebbae2addd5669fd (patch)
tree0c78ea550c8eb39ebd277dcbdb2495c0a0d08276
parentb50c1b243e09284b7bbfb81c1819d358d024168d (diff)
downloadrust-ba82f54b04f429d29b0d7c5aebbae2addd5669fd.tar.gz
rust-ba82f54b04f429d29b0d7c5aebbae2addd5669fd.zip
use RawConst in miri
-rw-r--r--src/librustc_mir/const_eval.rs14
-rw-r--r--src/librustc_mir/interpret/eval_context.rs14
-rw-r--r--src/librustc_mir/interpret/operand.rs28
-rw-r--r--src/librustc_mir/interpret/place.rs10
-rw-r--r--src/librustc_mir/transform/const_prop.rs6
5 files changed, 32 insertions, 40 deletions
diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs
index 4e727de5358..3b32fe21adf 100644
--- a/src/librustc_mir/const_eval.rs
+++ b/src/librustc_mir/const_eval.rs
@@ -99,8 +99,7 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>(
     eval_body_using_ecx(&mut ecx, cid, Some(mir), param_env)
 }
 
-// FIXME: This thing is a bad hack. We should get rid of it.  Ideally constants are always
-// in an allocation.
+// FIXME: These two conversion functions are bad hacks.  We should just always use allocations.
 pub fn op_to_const<'tcx>(
     ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
     op: OpTy<'tcx>,
@@ -146,6 +145,13 @@ pub fn op_to_const<'tcx>(
     };
     Ok(ty::Const::from_const_value(ecx.tcx.tcx, val, op.layout.ty))
 }
+pub fn const_to_op<'tcx>(
+    ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
+    cnst: &ty::Const<'tcx>,
+) -> EvalResult<'tcx, OpTy<'tcx>> {
+    let op = ecx.const_value_to_op(cnst.val)?;
+    Ok(OpTy { op, layout: ecx.layout_of(cnst.ty)? })
+}
 
 fn eval_body_and_ecx<'a, 'mir, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -496,7 +502,7 @@ pub fn const_field<'a, 'tcx>(
     let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
     let result = (|| {
         // get the operand again
-        let op = ecx.const_to_op(value)?;
+        let op = const_to_op(&ecx, value)?;
         // downcast
         let down = match variant {
             None => op,
@@ -523,7 +529,7 @@ pub fn const_variant_index<'a, 'tcx>(
 ) -> EvalResult<'tcx, VariantIdx> {
     trace!("const_variant_index: {:?}, {:?}", instance, val);
     let ecx = mk_eval_cx(tcx, instance, param_env).unwrap();
-    let op = ecx.const_to_op(val)?;
+    let op = const_to_op(&ecx, val)?;
     Ok(ecx.read_discriminant(op)?.1)
 }
 
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index ce7269d1e78..1d7eae50e71 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -588,18 +588,22 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
         Ok(())
     }
 
-    pub fn const_eval(&self, gid: GlobalId<'tcx>) -> EvalResult<'tcx, &'tcx ty::Const<'tcx>> {
+    pub fn const_eval_raw(
+        &self,
+        gid: GlobalId<'tcx>,
+    ) -> EvalResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
         let param_env = if self.tcx.is_static(gid.instance.def_id()).is_some() {
             ty::ParamEnv::reveal_all()
         } else {
             self.param_env
         };
-        self.tcx.const_eval(param_env.and(gid)).map_err(|err| {
+        let val = self.tcx.const_eval_raw(param_env.and(gid)).map_err(|err| {
             match err {
-                ErrorHandled::Reported => EvalErrorKind::ReferencedConstant.into(),
-                ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric.into(),
+                ErrorHandled::Reported => EvalErrorKind::ReferencedConstant,
+                ErrorHandled::TooGeneric => EvalErrorKind::TooGeneric,
             }
-        })
+        })?;
+        self.raw_const_to_mplace(val)
     }
 
     pub fn dump_place(&self, place: Place<M::PointerTag>) {
diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs
index 16f1e487f59..5d993cfee08 100644
--- a/src/librustc_mir/interpret/operand.rs
+++ b/src/librustc_mir/interpret/operand.rs
@@ -13,7 +13,7 @@
 
 use std::convert::TryInto;
 
-use rustc::{mir, ty};
+use rustc::mir;
 use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt, VariantIdx};
 
 use rustc::mir::interpret::{
@@ -535,9 +535,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
             .collect()
     }
 
-    // Also used e.g. when miri runs into a constant.
-    // FIXME: Can we avoid converting with ConstValue and Const?  We should be using RawConst.
-    fn const_value_to_op(
+    // Used when miri runs into a constant, and by CTFE.
+    // FIXME: CTFE should use allocations, then we can make this private (embed it into
+    // `eval_operand`, ideally).
+    pub(crate) fn const_value_to_op(
         &self,
         val: ConstValue<'tcx>,
     ) -> EvalResult<'tcx, Operand<M::PointerTag>> {
@@ -545,10 +546,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
         match val {
             ConstValue::Unevaluated(def_id, substs) => {
                 let instance = self.resolve(def_id, substs)?;
-                self.global_to_op(GlobalId {
+                Ok(*OpTy::from(self.const_eval_raw(GlobalId {
                     instance,
                     promoted: None,
-                })
+                })?))
             }
             ConstValue::ByRef(id, alloc, offset) => {
                 // We rely on mutability being set correctly in that allocation to prevent writes
@@ -566,21 +567,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                 Ok(Operand::Immediate(Immediate::Scalar(x.into())).with_default_tag()),
         }
     }
-    pub fn const_to_op(
-        &self,
-        cnst: &ty::Const<'tcx>,
-    ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
-        let op = self.const_value_to_op(cnst.val)?;
-        Ok(OpTy { op, layout: self.layout_of(cnst.ty)? })
-    }
-
-    pub(super) fn global_to_op(
-        &self,
-        gid: GlobalId<'tcx>
-    ) -> EvalResult<'tcx, Operand<M::PointerTag>> {
-        let cv = self.const_eval(gid)?;
-        self.const_value_to_op(cv.val)
-    }
 
     /// Read discriminant, return the runtime value as well as the variant index.
     pub fn read_discriminant(
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 104d66f7bde..9f248d46350 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -553,16 +553,10 @@ where
         Ok(match *mir_place {
             Promoted(ref promoted) => {
                 let instance = self.frame().instance;
-                let op = self.global_to_op(GlobalId {
+                self.const_eval_raw(GlobalId {
                     instance,
                     promoted: Some(promoted.0),
-                })?;
-                let mplace = op.to_mem_place(); // these are always in memory
-                let ty = self.monomorphize(promoted.1, self.substs());
-                MPlaceTy {
-                    mplace,
-                    layout: self.layout_of(ty)?,
-                }
+                })?
             }
 
             Static(ref static_) => {
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index 6b8233c941e..661ca4773b4 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -29,7 +29,9 @@ use rustc::ty::layout::{
 };
 
 use interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind};
-use const_eval::{CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_borrowck_eval_cx};
+use const_eval::{
+    CompileTimeInterpreter, const_to_op, error_to_const_error, eval_promoted, mk_borrowck_eval_cx
+};
 use transform::{MirPass, MirSource};
 
 pub struct ConstProp;
@@ -262,7 +264,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
         source_info: SourceInfo,
     ) -> Option<Const<'tcx>> {
         self.ecx.tcx.span = source_info.span;
-        match self.ecx.const_to_op(c.literal) {
+        match const_to_op(&self.ecx, c.literal) {
             Ok(op) => {
                 Some((op, c.span))
             },