about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_mir/interpret/cast.rs20
-rw-r--r--src/librustc_mir/interpret/mod.rs2
-rw-r--r--src/librustc_mir/interpret/validity.rs5
-rw-r--r--src/librustc_mir/interpret/visitor.rs12
4 files changed, 23 insertions, 16 deletions
diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs
index 118539fc58e..7d636b77ced 100644
--- a/src/librustc_mir/interpret/cast.rs
+++ b/src/librustc_mir/interpret/cast.rs
@@ -44,16 +44,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
             }
 
             Misc => {
+                let src_layout = src.layout;
                 let src = self.read_immediate(src)?;
 
-                if self.type_is_fat_ptr(src.layout.ty) {
-                    match (*src, self.type_is_fat_ptr(dest.layout.ty)) {
+                // There are no casts to references
+                assert!(!dest.layout.ty.is_region_ptr());
+                // Hence we make all casts erase the tag
+                let src = src.erase_tag().with_default_tag();
+
+                if self.type_is_fat_ptr(src_layout.ty) {
+                    match (src, self.type_is_fat_ptr(dest.layout.ty)) {
                         // pointers to extern types
                         (Immediate::Scalar(_),_) |
                         // slices and trait objects to other slices/trait objects
                         (Immediate::ScalarPair(..), true) => {
                             // No change to immediate
-                            self.write_immediate(*src, dest)?;
+                            self.write_immediate(src, dest)?;
                         }
                         // slices and trait objects to thin pointers (dropping the metadata)
                         (Immediate::ScalarPair(data, _), false) => {
@@ -61,11 +67,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         }
                     }
                 } else {
-                    match src.layout.variants {
+                    match src_layout.variants {
                         layout::Variants::Single { index } => {
-                            if let Some(def) = src.layout.ty.ty_adt_def() {
+                            if let Some(def) = src_layout.ty.ty_adt_def() {
                                 // Cast from a univariant enum
-                                assert!(src.layout.is_zst());
+                                assert!(src_layout.is_zst());
                                 let discr_val = def
                                     .discriminant_for_variant(*self.tcx, index)
                                     .val;
@@ -78,7 +84,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
                         layout::Variants::NicheFilling { .. } => {},
                     }
 
-                    let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?;
+                    let dest_val = self.cast_scalar(src.to_scalar()?, src_layout, dest.layout)?;
                     self.write_scalar(dest_val, dest)?;
                 }
             }
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index 82fe08fa038..96ea0d50949 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -39,6 +39,6 @@ pub use self::machine::{Machine, AllocMap, MayLeak};
 
 pub use self::operand::{ScalarMaybeUndef, Immediate, ImmTy, Operand, OpTy};
 
-pub use self::visitor::ValueVisitor;
+pub use self::visitor::{ValueVisitor, MutValueVisitor};
 
 pub use self::validity::RefTracking;
diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs
index a342cf6f647..ad7ffd291be 100644
--- a/src/librustc_mir/interpret/validity.rs
+++ b/src/librustc_mir/interpret/validity.rs
@@ -21,7 +21,7 @@ use rustc::mir::interpret::{
 };
 
 use super::{
-    OpTy, MPlaceTy, ImmTy, Machine, EvalContext, ValueVisitor
+    OpTy, MPlaceTy, Machine, EvalContext, ValueVisitor
 };
 
 macro_rules! validation_failure {
@@ -281,8 +281,9 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
         }
     }
 
-    fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
+    fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
     {
+        let value = self.ecx.read_immediate(value)?;
         // Go over all the primitive types
         let ty = value.layout.ty;
         match ty.sty {
diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs
index 4a470456432..f0a71242599 100644
--- a/src/librustc_mir/interpret/visitor.rs
+++ b/src/librustc_mir/interpret/visitor.rs
@@ -8,7 +8,7 @@ use rustc::mir::interpret::{
 };
 
 use super::{
-    Machine, EvalContext, MPlaceTy, OpTy, ImmTy,
+    Machine, EvalContext, MPlaceTy, OpTy,
 };
 
 // A thing that we can project into, and that has a layout.
@@ -201,9 +201,11 @@ macro_rules! make_value_visitor {
             { Ok(()) }
 
             /// Called whenever we reach a value of primitive type.  There can be no recursion
-            /// below such a value.  This is the leave function.
+            /// below such a value.  This is the leaf function.
+            /// We do *not* provide an `ImmTy` here because some implementations might want
+            /// to write to the place this primitive lives in.
             #[inline(always)]
-            fn visit_primitive(&mut self, _val: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
+            fn visit_primitive(&mut self, _v: Self::V) -> EvalResult<'tcx>
             { Ok(()) }
 
             // Default recursors. Not meant to be overloaded.
@@ -279,9 +281,7 @@ macro_rules! make_value_visitor {
                     _ => v.layout().ty.builtin_deref(true).is_some(),
                 };
                 if primitive {
-                    let op = v.to_op(self.ecx())?;
-                    let val = self.ecx().read_immediate(op)?;
-                    return self.visit_primitive(val);
+                    return self.visit_primitive(v);
                 }
 
                 // Proceed into the fields.