From c5bc83b60d10492f8e71461b03f5adb8505e53d6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 13 Nov 2018 11:14:18 +0100 Subject: [PATCH 1/3] expose MutValueVisitor --- src/librustc_mir/interpret/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 82fe08fa038a4..96ea0d5094966 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; From e4d03f82b582824d2b6c3fb68420883d26598178 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 13 Nov 2018 12:44:40 +0100 Subject: [PATCH 2/3] miri value visitor: provide place when visiting a primitive --- src/librustc_mir/interpret/validity.rs | 5 +++-- src/librustc_mir/interpret/visitor.rs | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index c3554512806b3..229f48381eaa4 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 4a47045643253..f0a71242599bf 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. From a7b312f8255db978f0446cf62383402fee02bae3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 17 Nov 2018 09:08:30 +0100 Subject: [PATCH 3/3] erase the tag on casts involving (raw) pointers --- src/librustc_mir/interpret/cast.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 118539fc58ebf..7d636b77ced4c 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)?; } }