]> git.lizzy.rs Git - rust.git/commitdiff
Add a `const_eval` helper to `InterpCx`
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Sun, 22 Dec 2019 19:56:01 +0000 (20:56 +0100)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Thu, 26 Dec 2019 21:50:18 +0000 (22:50 +0100)
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/intrinsics.rs
src/librustc_mir/interpret/operand.rs

index 76f74a3ecaa69acb2d26bbc566c6fdba0d27d403..da4156c2719fdcca5aca5580b3db840b89273e82 100644 (file)
@@ -20,8 +20,8 @@
 use syntax::source_map::{self, Span, DUMMY_SP};
 
 use super::{
-    Immediate, MPlaceTy, Machine, MemPlace, Memory, Operand, Place, PlaceTy, ScalarMaybeUndef,
-    StackPopInfo,
+    Immediate, MPlaceTy, Machine, MemPlace, Memory, OpTy, Operand, Place, PlaceTy,
+    ScalarMaybeUndef, StackPopInfo,
 };
 
 pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
@@ -754,6 +754,24 @@ pub(super) fn deallocate_local(
         Ok(())
     }
 
+    pub(super) fn const_eval(
+        &self,
+        gid: GlobalId<'tcx>,
+    ) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
+        // For statics we pick `ParamEnv::reveal_all`, because statics don't have generics
+        // and thus don't care about the parameter environment. While we could just use
+        // `self.param_env`, that would mean we invoke the query to evaluate the static
+        // with different parameter environments, thus causing the static to be evaluated
+        // multiple times.
+        let param_env = if self.tcx.is_static(gid.instance.def_id()) {
+            ty::ParamEnv::reveal_all()
+        } else {
+            self.param_env
+        };
+        let val = self.tcx.const_eval(param_env.and(gid))?;
+        self.eval_const_to_op(val, None)
+    }
+
     pub fn const_eval_raw(
         &self,
         gid: GlobalId<'tcx>,
index 8e4dc87451c326dd845a2e5ef2faf2ac8d8f6f5a..eb7657f780c56da4538df6e62f9f3c8e1b45fa48 100644 (file)
@@ -118,9 +118,8 @@ pub fn emulate_intrinsic(
             | sym::size_of
             | sym::type_id
             | sym::type_name => {
-                let val =
-                    self.tcx.const_eval_instance(self.param_env, instance, Some(self.tcx.span))?;
-                let val = self.eval_const_to_op(val, None)?;
+                let gid = GlobalId { instance, promoted: None };
+                let val = self.const_eval(gid)?;
                 self.copy_op(val, dest)?;
             }
 
index 694ffaa83e40b243093261da1f53535d3c68e805..fc63847433b5c0859a7402d04545b56d6a2ff553 100644 (file)
@@ -578,16 +578,6 @@ pub(super) fn eval_operands(
             ty::ConstKind::Param(_) => throw_inval!(TooGeneric),
             ty::ConstKind::Unevaluated(def_id, substs) => {
                 let instance = self.resolve(def_id, substs)?;
-                // For statics we pick `ParamEnv::reveal_all`, because statics don't have generics
-                // and thus don't care about the parameter environment. While we could just use
-                // `self.param_env`, that would mean we invoke the query to evaluate the static
-                // with different parameter environments, thus causing the static to be evaluated
-                // multiple times.
-                let param_env = if self.tcx.is_static(def_id) {
-                    ty::ParamEnv::reveal_all()
-                } else {
-                    self.param_env
-                };
                 // We use `const_eval` here and `const_eval_raw` elsewhere in mir interpretation.
                 // The reason we use `const_eval_raw` everywhere else is to prevent cycles during
                 // validation, because validation automatically reads through any references, thus
@@ -595,11 +585,7 @@ pub(super) fn eval_operands(
                 // problem here, because we need an operand and operands are always reads.
                 // FIXME(oli-obk): eliminate all the `const_eval_raw` usages when we get rid of
                 // `StaticKind` once and for all.
-                let val =
-                    self.tcx.const_eval(param_env.and(GlobalId { instance, promoted: None }))?;
-                // "recurse". This is only ever going into a recusion depth of 1, because after
-                // `const_eval` we don't have `Unevaluated` anymore.
-                return self.eval_const_to_op(val, layout);
+                return self.const_eval(GlobalId { instance, promoted: None });
             }
             ty::ConstKind::Value(val_val) => val_val,
         };