Skip to content

Commit cf221de

Browse files
authored
Rollup merge of rust-lang#55916 - RalfJung:mut-visitor, r=oli-obk
Make miri value visitor usfeful for mutation ~~This is based on top of rust-lang#55716, [click here](RalfJung/rust@escape-to-raw...RalfJung:mut-visitor) for just the new commits.~~ r? @oli-obk
2 parents 95795ca + a7b312f commit cf221de

File tree

4 files changed

+23
-16
lines changed

4 files changed

+23
-16
lines changed

src/librustc_mir/interpret/cast.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -44,28 +44,34 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
4444
}
4545

4646
Misc => {
47+
let src_layout = src.layout;
4748
let src = self.read_immediate(src)?;
4849

49-
if self.type_is_fat_ptr(src.layout.ty) {
50-
match (*src, self.type_is_fat_ptr(dest.layout.ty)) {
50+
// There are no casts to references
51+
assert!(!dest.layout.ty.is_region_ptr());
52+
// Hence we make all casts erase the tag
53+
let src = src.erase_tag().with_default_tag();
54+
55+
if self.type_is_fat_ptr(src_layout.ty) {
56+
match (src, self.type_is_fat_ptr(dest.layout.ty)) {
5157
// pointers to extern types
5258
(Immediate::Scalar(_),_) |
5359
// slices and trait objects to other slices/trait objects
5460
(Immediate::ScalarPair(..), true) => {
5561
// No change to immediate
56-
self.write_immediate(*src, dest)?;
62+
self.write_immediate(src, dest)?;
5763
}
5864
// slices and trait objects to thin pointers (dropping the metadata)
5965
(Immediate::ScalarPair(data, _), false) => {
6066
self.write_scalar(data, dest)?;
6167
}
6268
}
6369
} else {
64-
match src.layout.variants {
70+
match src_layout.variants {
6571
layout::Variants::Single { index } => {
66-
if let Some(def) = src.layout.ty.ty_adt_def() {
72+
if let Some(def) = src_layout.ty.ty_adt_def() {
6773
// Cast from a univariant enum
68-
assert!(src.layout.is_zst());
74+
assert!(src_layout.is_zst());
6975
let discr_val = def
7076
.discriminant_for_variant(*self.tcx, index)
7177
.val;
@@ -78,7 +84,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
7884
layout::Variants::NicheFilling { .. } => {},
7985
}
8086

81-
let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?;
87+
let dest_val = self.cast_scalar(src.to_scalar()?, src_layout, dest.layout)?;
8288
self.write_scalar(dest_val, dest)?;
8389
}
8490
}

src/librustc_mir/interpret/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,6 @@ pub use self::machine::{Machine, AllocMap, MayLeak};
3939

4040
pub use self::operand::{ScalarMaybeUndef, Immediate, ImmTy, Operand, OpTy};
4141

42-
pub use self::visitor::ValueVisitor;
42+
pub use self::visitor::{ValueVisitor, MutValueVisitor};
4343

4444
pub use self::validity::RefTracking;

src/librustc_mir/interpret/validity.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc::mir::interpret::{
2121
};
2222

2323
use super::{
24-
OpTy, MPlaceTy, ImmTy, Machine, EvalContext, ValueVisitor
24+
OpTy, MPlaceTy, Machine, EvalContext, ValueVisitor
2525
};
2626

2727
macro_rules! validation_failure {
@@ -281,8 +281,9 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
281281
}
282282
}
283283

284-
fn visit_primitive(&mut self, value: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
284+
fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
285285
{
286+
let value = self.ecx.read_immediate(value)?;
286287
// Go over all the primitive types
287288
let ty = value.layout.ty;
288289
match ty.sty {

src/librustc_mir/interpret/visitor.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use rustc::mir::interpret::{
88
};
99

1010
use super::{
11-
Machine, EvalContext, MPlaceTy, OpTy, ImmTy,
11+
Machine, EvalContext, MPlaceTy, OpTy,
1212
};
1313

1414
// A thing that we can project into, and that has a layout.
@@ -201,9 +201,11 @@ macro_rules! make_value_visitor {
201201
{ Ok(()) }
202202

203203
/// Called whenever we reach a value of primitive type. There can be no recursion
204-
/// below such a value. This is the leave function.
204+
/// below such a value. This is the leaf function.
205+
/// We do *not* provide an `ImmTy` here because some implementations might want
206+
/// to write to the place this primitive lives in.
205207
#[inline(always)]
206-
fn visit_primitive(&mut self, _val: ImmTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
208+
fn visit_primitive(&mut self, _v: Self::V) -> EvalResult<'tcx>
207209
{ Ok(()) }
208210

209211
// Default recursors. Not meant to be overloaded.
@@ -279,9 +281,7 @@ macro_rules! make_value_visitor {
279281
_ => v.layout().ty.builtin_deref(true).is_some(),
280282
};
281283
if primitive {
282-
let op = v.to_op(self.ecx())?;
283-
let val = self.ecx().read_immediate(op)?;
284-
return self.visit_primitive(val);
284+
return self.visit_primitive(v);
285285
}
286286

287287
// Proceed into the fields.

0 commit comments

Comments
 (0)