Pass PlaceTy by reference not value

This commit is contained in:
Tomasz Miąsko 2021-02-15 00:00:00 +00:00
parent e915cf45dc
commit fe0c46d07e
13 changed files with 91 additions and 87 deletions

View File

@ -56,7 +56,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
ecx.push_stack_frame(
cid.instance,
body,
Some(ret.into()),
Some(&ret.into()),
StackPopCleanup::None { cleanup: false },
)?;

View File

@ -222,7 +222,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
instance: ty::Instance<'tcx>,
_abi: Abi,
args: &[OpTy<'tcx>],
_ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
_ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>, // unwinding is not supported in consts
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
debug!("find_mir_or_eval_fn: {:?}", instance);
@ -262,7 +262,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
ecx: &mut InterpCx<'mir, 'tcx, Self>,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx>],
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
// Shared intrinsics.
@ -366,7 +366,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
fn box_alloc(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
_dest: PlaceTy<'tcx>,
_dest: &PlaceTy<'tcx>,
) -> InterpResult<'tcx> {
Err(ConstEvalErrKind::NeedsRfc("heap allocations via `box` keyword".to_string()).into())
}

View File

@ -20,7 +20,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
src: &OpTy<'tcx, M::PointerTag>,
cast_kind: CastKind,
cast_ty: Ty<'tcx>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
use rustc_middle::mir::CastKind::*;
// FIXME: In which cases should we trigger UB when the source is uninit?
@ -260,7 +260,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
fn unsize_into_ptr(
&mut self,
src: &OpTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
// The pointee types
source_ty: Ty<'tcx>,
cast_ty: Ty<'tcx>,
@ -302,7 +302,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&mut self,
src: &OpTy<'tcx, M::PointerTag>,
cast_ty: TyAndLayout<'tcx>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
trace!("Unsizing {:?} of type {} into {:?}", *src, src.layout.ty, cast_ty.ty);
match (&src.layout.ty.kind(), &cast_ty.ty.kind()) {
@ -340,9 +340,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let src_field = self.operand_field(src, i)?;
let dst_field = self.place_field(dest, i)?;
if src_field.layout.ty == cast_ty_field.ty {
self.copy_op(&src_field, dst_field)?;
self.copy_op(&src_field, &dst_field)?;
} else {
self.unsize_into(&src_field, cast_ty_field, dst_field)?;
self.unsize_into(&src_field, cast_ty_field, &dst_field)?;
}
}
Ok(())

View File

@ -654,7 +654,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&mut self,
instance: ty::Instance<'tcx>,
body: &'mir mir::Body<'tcx>,
return_place: Option<PlaceTy<'tcx, M::PointerTag>>,
return_place: Option<&PlaceTy<'tcx, M::PointerTag>>,
return_to_block: StackPopCleanup,
) -> InterpResult<'tcx> {
// first push a stack frame so we have access to the local substs
@ -662,7 +662,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
body,
loc: Err(body.span), // Span used for errors caused during preamble.
return_to_block,
return_place,
return_place: return_place.copied(),
// empty local array, we fill it in below, after we are inside the stack frame and
// all methods actually know about the frame
locals: IndexVec::new(),
@ -777,10 +777,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
if !unwinding {
// Copy the return value to the caller's stack frame.
if let Some(return_place) = frame.return_place {
if let Some(ref return_place) = frame.return_place {
let op = self.access_local(&frame, mir::RETURN_PLACE, None)?;
self.copy_op_transmute(&op, return_place)?;
trace!("{:?}", self.dump_place(*return_place));
trace!("{:?}", self.dump_place(**return_place));
} else {
throw_ub!(Unreachable);
}

View File

@ -115,7 +115,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&mut self,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, M::PointerTag>],
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
) -> InterpResult<'tcx, bool> {
let substs = instance.substs;
let intrinsic_name = self.tcx.item_name(instance.def_id());
@ -459,7 +459,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
for i in 0..len {
let place = self.place_index(dest, i)?;
let value = if i == index { *elem } else { self.operand_index(input, i)? };
self.copy_op(&value, place)?;
self.copy_op(&value, &place)?;
}
}
sym::simd_extract => {
@ -492,7 +492,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
_ => return Ok(false),
}
trace!("{:?}", self.dump_place(*dest));
trace!("{:?}", self.dump_place(**dest));
self.go_to_block(ret);
Ok(true)
}
@ -501,7 +501,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&mut self,
a: &ImmTy<'tcx, M::PointerTag>,
b: &ImmTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
// Performs an exact division, resulting in undefined behavior where
// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.

View File

@ -92,11 +92,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let location = self.allocate(loc_layout, MemoryKind::CallerLocation);
// Initialize fields.
self.write_immediate(file.to_ref(), self.mplace_field(location, 0).unwrap().into())
self.write_immediate(file.to_ref(), &self.mplace_field(location, 0).unwrap().into())
.expect("writing to memory we just allocated cannot fail");
self.write_scalar(line, self.mplace_field(location, 1).unwrap().into())
self.write_scalar(line, &self.mplace_field(location, 1).unwrap().into())
.expect("writing to memory we just allocated cannot fail");
self.write_scalar(col, self.mplace_field(location, 2).unwrap().into())
self.write_scalar(col, &self.mplace_field(location, 2).unwrap().into())
.expect("writing to memory we just allocated cannot fail");
location

View File

@ -157,7 +157,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
instance: ty::Instance<'tcx>,
abi: Abi,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
@ -168,7 +168,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
fn_val: Self::ExtraFnVal,
abi: Abi,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx>;
@ -178,7 +178,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
ecx: &mut InterpCx<'mir, 'tcx, Self>,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Self::PointerTag>],
ret: Option<(PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
ret: Option<(&PlaceTy<'tcx, Self::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx>;
@ -207,7 +207,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
/// Heap allocations via the `box` keyword.
fn box_alloc(
ecx: &mut InterpCx<'mir, 'tcx, Self>,
dest: PlaceTy<'tcx, Self::PointerTag>,
dest: &PlaceTy<'tcx, Self::PointerTag>,
) -> InterpResult<'tcx>;
/// Called to read the specified `local` from the `frame`.
@ -327,7 +327,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
fn retag(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
_kind: mir::RetagKind,
_place: PlaceTy<'tcx, Self::PointerTag>,
_place: &PlaceTy<'tcx, Self::PointerTag>,
) -> InterpResult<'tcx> {
Ok(())
}
@ -420,7 +420,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
fn_val: !,
_abi: Abi,
_args: &[OpTy<$tcx>],
_ret: Option<(PlaceTy<$tcx>, mir::BasicBlock)>,
_ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>,
_unwind: Option<mir::BasicBlock>,
) -> InterpResult<$tcx> {
match fn_val {}

View File

@ -462,9 +462,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
#[inline(always)]
pub fn place_to_op(
&self,
place: PlaceTy<'tcx, M::PointerTag>,
place: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
let op = match *place {
let op = match **place {
Place::Ptr(mplace) => Operand::Indirect(mplace),
Place::Local { frame, local } => {
*self.access_local(&self.stack()[frame], local, None)?

View File

@ -16,7 +16,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
op: mir::BinOp,
left: &ImmTy<'tcx, M::PointerTag>,
right: &ImmTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
let (val, overflowed, ty) = self.overflowing_binary_op(op, &left, &right)?;
debug_assert_eq!(
@ -36,7 +36,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
op: mir::BinOp,
left: &ImmTy<'tcx, M::PointerTag>,
right: &ImmTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
let (val, _overflowed, ty) = self.overflowing_binary_op(op, left, right)?;
assert_eq!(ty, dest.layout.ty, "type mismatch for result of {:?}", op);

View File

@ -592,7 +592,7 @@ where
/// into the field of a local `ScalarPair`, we have to first allocate it.
pub fn place_field(
&mut self,
base: PlaceTy<'tcx, M::PointerTag>,
base: &PlaceTy<'tcx, M::PointerTag>,
field: usize,
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
// FIXME: We could try to be smarter and avoid allocation for fields that span the
@ -603,7 +603,7 @@ where
pub fn place_index(
&mut self,
base: PlaceTy<'tcx, M::PointerTag>,
base: &PlaceTy<'tcx, M::PointerTag>,
index: u64,
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
let mplace = self.force_allocation(base)?;
@ -612,7 +612,7 @@ where
pub fn place_downcast(
&self,
base: PlaceTy<'tcx, M::PointerTag>,
base: &PlaceTy<'tcx, M::PointerTag>,
variant: VariantIdx,
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
// Downcast just changes the layout
@ -622,7 +622,7 @@ where
}
Place::Local { .. } => {
let layout = base.layout.for_variant(self, variant);
PlaceTy { layout, ..base }
PlaceTy { layout, ..*base }
}
})
}
@ -630,7 +630,7 @@ where
/// Projects into a place.
pub fn place_projection(
&mut self,
base: PlaceTy<'tcx, M::PointerTag>,
base: &PlaceTy<'tcx, M::PointerTag>,
&proj_elem: &mir::ProjectionElem<mir::Local, Ty<'tcx>>,
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
use rustc_middle::mir::ProjectionElem::*;
@ -660,7 +660,7 @@ where
};
for elem in place.projection.iter() {
place_ty = self.place_projection(place_ty, &elem)?
place_ty = self.place_projection(&place_ty, &elem)?
}
trace!("{:?}", self.dump_place(place_ty.place));
@ -681,7 +681,7 @@ where
pub fn write_scalar(
&mut self,
val: impl Into<ScalarMaybeUninit<M::PointerTag>>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
self.write_immediate(Immediate::Scalar(val.into()), dest)
}
@ -691,7 +691,7 @@ where
pub fn write_immediate(
&mut self,
src: Immediate<M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
self.write_immediate_no_validate(src, dest)?;
@ -726,7 +726,7 @@ where
fn write_immediate_no_validate(
&mut self,
src: Immediate<M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
if cfg!(debug_assertions) {
// This is a very common path, avoid some checks in release mode
@ -844,7 +844,7 @@ where
pub fn copy_op(
&mut self,
src: &OpTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
self.copy_op_no_validate(src, dest)?;
@ -863,7 +863,7 @@ where
fn copy_op_no_validate(
&mut self,
src: &OpTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
// We do NOT compare the types for equality, because well-typed code can
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
@ -922,7 +922,7 @@ where
pub fn copy_op_transmute(
&mut self,
src: &OpTy<'tcx, M::PointerTag>,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
if mir_assign_valid_types(*self.tcx, self.param_env, src.layout, dest.layout) {
// Fast path: Just use normal `copy_op`
@ -959,7 +959,7 @@ where
let dest = self.force_allocation(dest)?;
self.copy_op_no_validate(
src,
PlaceTy::from(MPlaceTy { mplace: *dest, layout: src.layout }),
&PlaceTy::from(MPlaceTy { mplace: *dest, layout: src.layout }),
)?;
if M::enforce_validity(self) {
@ -980,7 +980,7 @@ where
/// version.
pub fn force_allocation_maybe_sized(
&mut self,
place: PlaceTy<'tcx, M::PointerTag>,
place: &PlaceTy<'tcx, M::PointerTag>,
meta: MemPlaceMeta<M::PointerTag>,
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, Option<Size>)> {
let (mplace, size) = match place.place {
@ -1025,7 +1025,7 @@ where
#[inline(always)]
pub fn force_allocation(
&mut self,
place: PlaceTy<'tcx, M::PointerTag>,
place: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
Ok(self.force_allocation_maybe_sized(place, MemPlaceMeta::None)?.0)
}
@ -1061,7 +1061,7 @@ where
pub fn write_discriminant(
&mut self,
variant_index: VariantIdx,
dest: PlaceTy<'tcx, M::PointerTag>,
dest: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
// Layout computation excludes uninhabited variants from consideration
// therefore there's no way to represent those variants in the given layout.
@ -1092,7 +1092,7 @@ where
let tag_val = size.truncate(discr_val);
let tag_dest = self.place_field(dest, tag_field)?;
self.write_scalar(Scalar::from_uint(tag_val, size), tag_dest)?;
self.write_scalar(Scalar::from_uint(tag_val, size), &tag_dest)?;
}
Variants::Multiple {
tag_encoding:
@ -1123,7 +1123,7 @@ where
)?;
// Write result.
let niche_dest = self.place_field(dest, tag_field)?;
self.write_immediate(*tag_val, niche_dest)?;
self.write_immediate(*tag_val, &niche_dest)?;
}
}
}

View File

@ -90,7 +90,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
SetDiscriminant { place, variant_index } => {
let dest = self.eval_place(**place)?;
self.write_discriminant(*variant_index, dest)?;
self.write_discriminant(*variant_index, &dest)?;
}
// Mark locals as alive
@ -110,7 +110,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Stacked Borrows.
Retag(kind, place) => {
let dest = self.eval_place(**place)?;
M::retag(self, *kind, dest)?;
M::retag(self, *kind, &dest)?;
}
// Statements we do not track.
@ -156,13 +156,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ThreadLocalRef(did) => {
let id = M::thread_local_static_alloc_id(self, did)?;
let val = self.global_base_pointer(id.into())?;
self.write_scalar(val, dest)?;
self.write_scalar(val, &dest)?;
}
Use(ref operand) => {
// Avoid recomputing the layout
let op = self.eval_operand(operand, Some(dest.layout))?;
self.copy_op(&op, dest)?;
self.copy_op(&op, &dest)?;
}
BinaryOp(bin_op, ref left, ref right) => {
@ -170,7 +170,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let left = self.read_immediate(&self.eval_operand(left, layout)?)?;
let layout = binop_right_homogeneous(bin_op).then_some(left.layout);
let right = self.read_immediate(&self.eval_operand(right, layout)?)?;
self.binop_ignore_overflow(bin_op, &left, &right, dest)?;
self.binop_ignore_overflow(bin_op, &left, &right, &dest)?;
}
CheckedBinaryOp(bin_op, ref left, ref right) => {
@ -178,7 +178,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let left = self.read_immediate(&self.eval_operand(left, None)?)?;
let layout = binop_right_homogeneous(bin_op).then_some(left.layout);
let right = self.read_immediate(&self.eval_operand(right, layout)?)?;
self.binop_with_overflow(bin_op, &left, &right, dest)?;
self.binop_with_overflow(bin_op, &left, &right, &dest)?;
}
UnaryOp(un_op, ref operand) => {
@ -186,15 +186,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let val = self.read_immediate(&self.eval_operand(operand, Some(dest.layout))?)?;
let val = self.unary_op(un_op, &val)?;
assert_eq!(val.layout, dest.layout, "layout mismatch for result of {:?}", un_op);
self.write_immediate(*val, dest)?;
self.write_immediate(*val, &dest)?;
}
Aggregate(ref kind, ref operands) => {
let (dest, active_field_index) = match **kind {
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
self.write_discriminant(variant_index, dest)?;
self.write_discriminant(variant_index, &dest)?;
if adt_def.is_enum() {
(self.place_downcast(dest, variant_index)?, active_field_index)
(self.place_downcast(&dest, variant_index)?, active_field_index)
} else {
(dest, active_field_index)
}
@ -207,21 +207,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Ignore zero-sized fields.
if !op.layout.is_zst() {
let field_index = active_field_index.unwrap_or(i);
let field_dest = self.place_field(dest, field_index)?;
self.copy_op(&op, field_dest)?;
let field_dest = self.place_field(&dest, field_index)?;
self.copy_op(&op, &field_dest)?;
}
}
}
Repeat(ref operand, _) => {
let op = self.eval_operand(operand, None)?;
let dest = self.force_allocation(dest)?;
let dest = self.force_allocation(&dest)?;
let length = dest.len(self)?;
if let Some(first_ptr) = self.check_mplace_access(dest, None)? {
// Write the first.
let first = self.mplace_field(dest, 0)?;
self.copy_op(&op, first.into())?;
self.copy_op(&op, &first.into())?;
if length > 1 {
let elem_size = first.layout.size;
@ -242,23 +242,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Len(place) => {
// FIXME(CTFE): don't allow computing the length of arrays in const eval
let src = self.eval_place(place)?;
let mplace = self.force_allocation(src)?;
let mplace = self.force_allocation(&src)?;
let len = mplace.len(self)?;
self.write_scalar(Scalar::from_machine_usize(len, self), dest)?;
self.write_scalar(Scalar::from_machine_usize(len, self), &dest)?;
}
AddressOf(_, place) | Ref(_, _, place) => {
let src = self.eval_place(place)?;
let place = self.force_allocation(src)?;
let place = self.force_allocation(&src)?;
if place.layout.size.bytes() > 0 {
// definitely not a ZST
assert!(place.ptr.is_ptr(), "non-ZST places should be normalized to `Pointer`");
}
self.write_immediate(place.to_ref(), dest)?;
self.write_immediate(place.to_ref(), &dest)?;
}
NullaryOp(mir::NullOp::Box, _) => {
M::box_alloc(self, dest)?;
M::box_alloc(self, &dest)?;
}
NullaryOp(mir::NullOp::SizeOf, ty) => {
@ -272,19 +272,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
);
throw_inval!(SizeOfUnsizedType(ty));
}
self.write_scalar(Scalar::from_machine_usize(layout.size.bytes(), self), dest)?;
self.write_scalar(Scalar::from_machine_usize(layout.size.bytes(), self), &dest)?;
}
Cast(cast_kind, ref operand, cast_ty) => {
let src = self.eval_operand(operand, None)?;
let cast_ty = self.subst_from_current_frame_and_normalize_erasing_regions(cast_ty);
self.cast(&src, cast_kind, cast_ty, dest)?;
self.cast(&src, cast_kind, cast_ty, &dest)?;
}
Discriminant(place) => {
let op = self.eval_place_to_op(place, None)?;
let discr_val = self.read_discriminant(&op)?.0;
self.write_scalar(discr_val, dest)?;
self.write_scalar(discr_val, &dest)?;
}
}

View File

@ -78,8 +78,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
),
};
let args = self.eval_operands(args)?;
let dest_place;
let ret = match destination {
Some((dest, ret)) => Some((self.eval_place(dest)?, ret)),
Some((dest, ret)) => {
dest_place = self.eval_place(dest)?;
Some((&dest_place, ret))
},
None => None,
};
self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup)?;
@ -96,7 +100,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
self.drop_in_place(place, instance, target, unwind)?;
self.drop_in_place(&place, instance, target, unwind)?;
}
Assert { ref cond, expected, ref msg, target, cleanup } => {
@ -180,7 +184,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&mut self,
rust_abi: bool,
caller_arg: &mut impl Iterator<Item = OpTy<'tcx, M::PointerTag>>,
callee_arg: PlaceTy<'tcx, M::PointerTag>,
callee_arg: &PlaceTy<'tcx, M::PointerTag>,
) -> InterpResult<'tcx> {
if rust_abi && callee_arg.layout.is_zst() {
// Nothing to do.
@ -211,7 +215,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
fn_val: FnVal<'tcx, M::ExtraFnVal>,
caller_abi: Abi,
args: &[OpTy<'tcx, M::PointerTag>],
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
unwind: Option<mir::BasicBlock>,
) -> InterpResult<'tcx> {
trace!("eval_fn_call: {:#?}", fn_val);
@ -344,12 +348,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
if Some(local) == body.spread_arg {
// Must be a tuple
for i in 0..dest.layout.fields.count() {
let dest = self.place_field(dest, i)?;
self.pass_argument(rust_abi, &mut caller_iter, dest)?;
let dest = self.place_field(&dest, i)?;
self.pass_argument(rust_abi, &mut caller_iter, &dest)?;
}
} else {
// Normal argument
self.pass_argument(rust_abi, &mut caller_iter, dest)?;
self.pass_argument(rust_abi, &mut caller_iter, &dest)?;
}
}
// Now we should have no more caller args
@ -426,7 +430,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
fn drop_in_place(
&mut self,
place: PlaceTy<'tcx, M::PointerTag>,
place: &PlaceTy<'tcx, M::PointerTag>,
instance: ty::Instance<'tcx>,
target: mir::BasicBlock,
unwind: Option<mir::BasicBlock>,
@ -457,7 +461,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
FnVal::Instance(instance),
Abi::Rust,
&[arg.into()],
Some((dest.into(), target)),
Some((&dest.into(), target)),
unwind,
)
}

View File

@ -197,7 +197,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
_instance: ty::Instance<'tcx>,
_abi: Abi,
_args: &[OpTy<'tcx>],
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
_ret: Option<(&PlaceTy<'tcx>, BasicBlock)>,
_unwind: Option<BasicBlock>,
) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> {
Ok(None)
@ -207,7 +207,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
_instance: ty::Instance<'tcx>,
_args: &[OpTy<'tcx>],
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
_ret: Option<(&PlaceTy<'tcx>, BasicBlock)>,
_unwind: Option<BasicBlock>,
) -> InterpResult<'tcx> {
throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp")
@ -237,7 +237,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
fn box_alloc(
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
_dest: PlaceTy<'tcx>,
_dest: &PlaceTy<'tcx>,
) -> InterpResult<'tcx> {
throw_machine_stop_str!("can't const prop heap allocations")
}
@ -392,12 +392,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
.filter(|ret_layout| {
!ret_layout.is_zst() && ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT)
})
.map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack));
.map(|ret_layout| ecx.allocate(ret_layout, MemoryKind::Stack).into());
ecx.push_stack_frame(
Instance::new(def_id, substs),
dummy_body,
ret.map(Into::into),
ret.as_ref(),
StackPopCleanup::None { cleanup: false },
)
.expect("failed to push initial stack frame");
@ -760,14 +760,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
match op {
BinOp::BitAnd => {
if arg_value == 0 {
this.ecx.write_immediate(*const_arg, dest)?;
this.ecx.write_immediate(*const_arg, &dest)?;
}
}
BinOp::BitOr => {
if arg_value == const_arg.layout.size.truncate(u128::MAX)
|| (const_arg.layout.ty.is_bool() && arg_value == 1)
{
this.ecx.write_immediate(*const_arg, dest)?;
this.ecx.write_immediate(*const_arg, &dest)?;
}
}
BinOp::Mul => {
@ -777,9 +777,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
const_arg.to_scalar()?.into(),
Scalar::from_bool(false).into(),
);
this.ecx.write_immediate(val, dest)?;
this.ecx.write_immediate(val, &dest)?;
} else {
this.ecx.write_immediate(*const_arg, dest)?;
this.ecx.write_immediate(*const_arg, &dest)?;
}
}
}