Rollup merge of #55916 - RalfJung:mut-visitor, r=oli-obk
Make miri value visitor usfeful for mutation ~~This is based on top of https://github.com/rust-lang/rust/pull/55716, [click here](https://github.com/RalfJung/rust/compare/escape-to-raw...RalfJung:mut-visitor) for just the new commits.~~ r? @oli-obk
This commit is contained in:
commit
c87c31b111
4 changed files with 23 additions and 16 deletions
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue