Pass PlaceTy by reference not value
This commit is contained in:
parent
e915cf45dc
commit
fe0c46d07e
13 changed files with 91 additions and 87 deletions
|
@ -56,7 +56,7 @@ fn eval_body_using_ecx<'mir, 'tcx>(
|
||||||
ecx.push_stack_frame(
|
ecx.push_stack_frame(
|
||||||
cid.instance,
|
cid.instance,
|
||||||
body,
|
body,
|
||||||
Some(ret.into()),
|
Some(&ret.into()),
|
||||||
StackPopCleanup::None { cleanup: false },
|
StackPopCleanup::None { cleanup: false },
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
@ -222,7 +222,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
_abi: Abi,
|
_abi: Abi,
|
||||||
args: &[OpTy<'tcx>],
|
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
|
_unwind: Option<mir::BasicBlock>, // unwinding is not supported in consts
|
||||||
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
|
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
|
||||||
debug!("find_mir_or_eval_fn: {:?}", instance);
|
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>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
args: &[OpTy<'tcx>],
|
args: &[OpTy<'tcx>],
|
||||||
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
|
ret: Option<(&PlaceTy<'tcx>, mir::BasicBlock)>,
|
||||||
_unwind: Option<mir::BasicBlock>,
|
_unwind: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// Shared intrinsics.
|
// Shared intrinsics.
|
||||||
|
@ -366,7 +366,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
|
||||||
|
|
||||||
fn box_alloc(
|
fn box_alloc(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_dest: PlaceTy<'tcx>,
|
_dest: &PlaceTy<'tcx>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
Err(ConstEvalErrKind::NeedsRfc("heap allocations via `box` keyword".to_string()).into())
|
Err(ConstEvalErrKind::NeedsRfc("heap allocations via `box` keyword".to_string()).into())
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
src: &OpTy<'tcx, M::PointerTag>,
|
src: &OpTy<'tcx, M::PointerTag>,
|
||||||
cast_kind: CastKind,
|
cast_kind: CastKind,
|
||||||
cast_ty: Ty<'tcx>,
|
cast_ty: Ty<'tcx>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
use rustc_middle::mir::CastKind::*;
|
use rustc_middle::mir::CastKind::*;
|
||||||
// FIXME: In which cases should we trigger UB when the source is uninit?
|
// 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(
|
fn unsize_into_ptr(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: &OpTy<'tcx, M::PointerTag>,
|
src: &OpTy<'tcx, M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
// The pointee types
|
// The pointee types
|
||||||
source_ty: Ty<'tcx>,
|
source_ty: Ty<'tcx>,
|
||||||
cast_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,
|
&mut self,
|
||||||
src: &OpTy<'tcx, M::PointerTag>,
|
src: &OpTy<'tcx, M::PointerTag>,
|
||||||
cast_ty: TyAndLayout<'tcx>,
|
cast_ty: TyAndLayout<'tcx>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
trace!("Unsizing {:?} of type {} into {:?}", *src, src.layout.ty, cast_ty.ty);
|
trace!("Unsizing {:?} of type {} into {:?}", *src, src.layout.ty, cast_ty.ty);
|
||||||
match (&src.layout.ty.kind(), &cast_ty.ty.kind()) {
|
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 src_field = self.operand_field(src, i)?;
|
||||||
let dst_field = self.place_field(dest, i)?;
|
let dst_field = self.place_field(dest, i)?;
|
||||||
if src_field.layout.ty == cast_ty_field.ty {
|
if src_field.layout.ty == cast_ty_field.ty {
|
||||||
self.copy_op(&src_field, dst_field)?;
|
self.copy_op(&src_field, &dst_field)?;
|
||||||
} else {
|
} else {
|
||||||
self.unsize_into(&src_field, cast_ty_field, dst_field)?;
|
self.unsize_into(&src_field, cast_ty_field, &dst_field)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -654,7 +654,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
&mut self,
|
&mut self,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
body: &'mir mir::Body<'tcx>,
|
body: &'mir mir::Body<'tcx>,
|
||||||
return_place: Option<PlaceTy<'tcx, M::PointerTag>>,
|
return_place: Option<&PlaceTy<'tcx, M::PointerTag>>,
|
||||||
return_to_block: StackPopCleanup,
|
return_to_block: StackPopCleanup,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// first push a stack frame so we have access to the local substs
|
// 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,
|
body,
|
||||||
loc: Err(body.span), // Span used for errors caused during preamble.
|
loc: Err(body.span), // Span used for errors caused during preamble.
|
||||||
return_to_block,
|
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
|
// empty local array, we fill it in below, after we are inside the stack frame and
|
||||||
// all methods actually know about the frame
|
// all methods actually know about the frame
|
||||||
locals: IndexVec::new(),
|
locals: IndexVec::new(),
|
||||||
|
@ -777,10 +777,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
if !unwinding {
|
if !unwinding {
|
||||||
// Copy the return value to the caller's stack frame.
|
// 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)?;
|
let op = self.access_local(&frame, mir::RETURN_PLACE, None)?;
|
||||||
self.copy_op_transmute(&op, return_place)?;
|
self.copy_op_transmute(&op, return_place)?;
|
||||||
trace!("{:?}", self.dump_place(*return_place));
|
trace!("{:?}", self.dump_place(**return_place));
|
||||||
} else {
|
} else {
|
||||||
throw_ub!(Unreachable);
|
throw_ub!(Unreachable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
&mut self,
|
&mut self,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
args: &[OpTy<'tcx, M::PointerTag>],
|
args: &[OpTy<'tcx, M::PointerTag>],
|
||||||
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
|
ret: Option<(&PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
|
||||||
) -> InterpResult<'tcx, bool> {
|
) -> InterpResult<'tcx, bool> {
|
||||||
let substs = instance.substs;
|
let substs = instance.substs;
|
||||||
let intrinsic_name = self.tcx.item_name(instance.def_id());
|
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 {
|
for i in 0..len {
|
||||||
let place = self.place_index(dest, i)?;
|
let place = self.place_index(dest, i)?;
|
||||||
let value = if i == index { *elem } else { self.operand_index(input, 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 => {
|
sym::simd_extract => {
|
||||||
|
@ -492,7 +492,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
_ => return Ok(false),
|
_ => return Ok(false),
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("{:?}", self.dump_place(*dest));
|
trace!("{:?}", self.dump_place(**dest));
|
||||||
self.go_to_block(ret);
|
self.go_to_block(ret);
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
@ -501,7 +501,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
&mut self,
|
&mut self,
|
||||||
a: &ImmTy<'tcx, M::PointerTag>,
|
a: &ImmTy<'tcx, M::PointerTag>,
|
||||||
b: &ImmTy<'tcx, M::PointerTag>,
|
b: &ImmTy<'tcx, M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// Performs an exact division, resulting in undefined behavior where
|
// Performs an exact division, resulting in undefined behavior where
|
||||||
// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
|
// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`.
|
||||||
|
|
|
@ -92,11 +92,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
let location = self.allocate(loc_layout, MemoryKind::CallerLocation);
|
let location = self.allocate(loc_layout, MemoryKind::CallerLocation);
|
||||||
|
|
||||||
// Initialize fields.
|
// 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");
|
.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");
|
.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");
|
.expect("writing to memory we just allocated cannot fail");
|
||||||
|
|
||||||
location
|
location
|
||||||
|
|
|
@ -157,7 +157,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
abi: Abi,
|
abi: Abi,
|
||||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
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>,
|
unwind: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
|
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>>;
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
fn_val: Self::ExtraFnVal,
|
fn_val: Self::ExtraFnVal,
|
||||||
abi: Abi,
|
abi: Abi,
|
||||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
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>,
|
unwind: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<'tcx>;
|
) -> InterpResult<'tcx>;
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
args: &[OpTy<'tcx, Self::PointerTag>],
|
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>,
|
unwind: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<'tcx>;
|
) -> InterpResult<'tcx>;
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
/// Heap allocations via the `box` keyword.
|
/// Heap allocations via the `box` keyword.
|
||||||
fn box_alloc(
|
fn box_alloc(
|
||||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
dest: PlaceTy<'tcx, Self::PointerTag>,
|
dest: &PlaceTy<'tcx, Self::PointerTag>,
|
||||||
) -> InterpResult<'tcx>;
|
) -> InterpResult<'tcx>;
|
||||||
|
|
||||||
/// Called to read the specified `local` from the `frame`.
|
/// Called to read the specified `local` from the `frame`.
|
||||||
|
@ -327,7 +327,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
||||||
fn retag(
|
fn retag(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_kind: mir::RetagKind,
|
_kind: mir::RetagKind,
|
||||||
_place: PlaceTy<'tcx, Self::PointerTag>,
|
_place: &PlaceTy<'tcx, Self::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
||||||
fn_val: !,
|
fn_val: !,
|
||||||
_abi: Abi,
|
_abi: Abi,
|
||||||
_args: &[OpTy<$tcx>],
|
_args: &[OpTy<$tcx>],
|
||||||
_ret: Option<(PlaceTy<$tcx>, mir::BasicBlock)>,
|
_ret: Option<(&PlaceTy<$tcx>, mir::BasicBlock)>,
|
||||||
_unwind: Option<mir::BasicBlock>,
|
_unwind: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<$tcx> {
|
) -> InterpResult<$tcx> {
|
||||||
match fn_val {}
|
match fn_val {}
|
||||||
|
|
|
@ -462,9 +462,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn place_to_op(
|
pub fn place_to_op(
|
||||||
&self,
|
&self,
|
||||||
place: PlaceTy<'tcx, M::PointerTag>,
|
place: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
|
||||||
let op = match *place {
|
let op = match **place {
|
||||||
Place::Ptr(mplace) => Operand::Indirect(mplace),
|
Place::Ptr(mplace) => Operand::Indirect(mplace),
|
||||||
Place::Local { frame, local } => {
|
Place::Local { frame, local } => {
|
||||||
*self.access_local(&self.stack()[frame], local, None)?
|
*self.access_local(&self.stack()[frame], local, None)?
|
||||||
|
|
|
@ -16,7 +16,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
op: mir::BinOp,
|
op: mir::BinOp,
|
||||||
left: &ImmTy<'tcx, M::PointerTag>,
|
left: &ImmTy<'tcx, M::PointerTag>,
|
||||||
right: &ImmTy<'tcx, M::PointerTag>,
|
right: &ImmTy<'tcx, M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let (val, overflowed, ty) = self.overflowing_binary_op(op, &left, &right)?;
|
let (val, overflowed, ty) = self.overflowing_binary_op(op, &left, &right)?;
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
|
@ -36,7 +36,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
op: mir::BinOp,
|
op: mir::BinOp,
|
||||||
left: &ImmTy<'tcx, M::PointerTag>,
|
left: &ImmTy<'tcx, M::PointerTag>,
|
||||||
right: &ImmTy<'tcx, M::PointerTag>,
|
right: &ImmTy<'tcx, M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let (val, _overflowed, ty) = self.overflowing_binary_op(op, left, right)?;
|
let (val, _overflowed, ty) = self.overflowing_binary_op(op, left, right)?;
|
||||||
assert_eq!(ty, dest.layout.ty, "type mismatch for result of {:?}", op);
|
assert_eq!(ty, dest.layout.ty, "type mismatch for result of {:?}", op);
|
||||||
|
|
|
@ -592,7 +592,7 @@ where
|
||||||
/// into the field of a local `ScalarPair`, we have to first allocate it.
|
/// into the field of a local `ScalarPair`, we have to first allocate it.
|
||||||
pub fn place_field(
|
pub fn place_field(
|
||||||
&mut self,
|
&mut self,
|
||||||
base: PlaceTy<'tcx, M::PointerTag>,
|
base: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
field: usize,
|
field: usize,
|
||||||
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||||
// FIXME: We could try to be smarter and avoid allocation for fields that span the
|
// FIXME: We could try to be smarter and avoid allocation for fields that span the
|
||||||
|
@ -603,7 +603,7 @@ where
|
||||||
|
|
||||||
pub fn place_index(
|
pub fn place_index(
|
||||||
&mut self,
|
&mut self,
|
||||||
base: PlaceTy<'tcx, M::PointerTag>,
|
base: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
index: u64,
|
index: u64,
|
||||||
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||||
let mplace = self.force_allocation(base)?;
|
let mplace = self.force_allocation(base)?;
|
||||||
|
@ -612,7 +612,7 @@ where
|
||||||
|
|
||||||
pub fn place_downcast(
|
pub fn place_downcast(
|
||||||
&self,
|
&self,
|
||||||
base: PlaceTy<'tcx, M::PointerTag>,
|
base: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
variant: VariantIdx,
|
variant: VariantIdx,
|
||||||
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||||
// Downcast just changes the layout
|
// Downcast just changes the layout
|
||||||
|
@ -622,7 +622,7 @@ where
|
||||||
}
|
}
|
||||||
Place::Local { .. } => {
|
Place::Local { .. } => {
|
||||||
let layout = base.layout.for_variant(self, variant);
|
let layout = base.layout.for_variant(self, variant);
|
||||||
PlaceTy { layout, ..base }
|
PlaceTy { layout, ..*base }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -630,7 +630,7 @@ where
|
||||||
/// Projects into a place.
|
/// Projects into a place.
|
||||||
pub fn place_projection(
|
pub fn place_projection(
|
||||||
&mut self,
|
&mut self,
|
||||||
base: PlaceTy<'tcx, M::PointerTag>,
|
base: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
&proj_elem: &mir::ProjectionElem<mir::Local, Ty<'tcx>>,
|
&proj_elem: &mir::ProjectionElem<mir::Local, Ty<'tcx>>,
|
||||||
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||||
use rustc_middle::mir::ProjectionElem::*;
|
use rustc_middle::mir::ProjectionElem::*;
|
||||||
|
@ -660,7 +660,7 @@ where
|
||||||
};
|
};
|
||||||
|
|
||||||
for elem in place.projection.iter() {
|
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));
|
trace!("{:?}", self.dump_place(place_ty.place));
|
||||||
|
@ -681,7 +681,7 @@ where
|
||||||
pub fn write_scalar(
|
pub fn write_scalar(
|
||||||
&mut self,
|
&mut self,
|
||||||
val: impl Into<ScalarMaybeUninit<M::PointerTag>>,
|
val: impl Into<ScalarMaybeUninit<M::PointerTag>>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
self.write_immediate(Immediate::Scalar(val.into()), dest)
|
self.write_immediate(Immediate::Scalar(val.into()), dest)
|
||||||
}
|
}
|
||||||
|
@ -691,7 +691,7 @@ where
|
||||||
pub fn write_immediate(
|
pub fn write_immediate(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: Immediate<M::PointerTag>,
|
src: Immediate<M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
self.write_immediate_no_validate(src, dest)?;
|
self.write_immediate_no_validate(src, dest)?;
|
||||||
|
|
||||||
|
@ -726,7 +726,7 @@ where
|
||||||
fn write_immediate_no_validate(
|
fn write_immediate_no_validate(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: Immediate<M::PointerTag>,
|
src: Immediate<M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
// This is a very common path, avoid some checks in release mode
|
// This is a very common path, avoid some checks in release mode
|
||||||
|
@ -844,7 +844,7 @@ where
|
||||||
pub fn copy_op(
|
pub fn copy_op(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: &OpTy<'tcx, M::PointerTag>,
|
src: &OpTy<'tcx, M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
self.copy_op_no_validate(src, dest)?;
|
self.copy_op_no_validate(src, dest)?;
|
||||||
|
|
||||||
|
@ -863,7 +863,7 @@ where
|
||||||
fn copy_op_no_validate(
|
fn copy_op_no_validate(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: &OpTy<'tcx, M::PointerTag>,
|
src: &OpTy<'tcx, M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// We do NOT compare the types for equality, because well-typed code can
|
// 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.
|
// actually "transmute" `&mut T` to `&T` in an assignment without a cast.
|
||||||
|
@ -922,7 +922,7 @@ where
|
||||||
pub fn copy_op_transmute(
|
pub fn copy_op_transmute(
|
||||||
&mut self,
|
&mut self,
|
||||||
src: &OpTy<'tcx, M::PointerTag>,
|
src: &OpTy<'tcx, M::PointerTag>,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
if mir_assign_valid_types(*self.tcx, self.param_env, src.layout, dest.layout) {
|
if mir_assign_valid_types(*self.tcx, self.param_env, src.layout, dest.layout) {
|
||||||
// Fast path: Just use normal `copy_op`
|
// Fast path: Just use normal `copy_op`
|
||||||
|
@ -959,7 +959,7 @@ where
|
||||||
let dest = self.force_allocation(dest)?;
|
let dest = self.force_allocation(dest)?;
|
||||||
self.copy_op_no_validate(
|
self.copy_op_no_validate(
|
||||||
src,
|
src,
|
||||||
PlaceTy::from(MPlaceTy { mplace: *dest, layout: src.layout }),
|
&PlaceTy::from(MPlaceTy { mplace: *dest, layout: src.layout }),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
if M::enforce_validity(self) {
|
if M::enforce_validity(self) {
|
||||||
|
@ -980,7 +980,7 @@ where
|
||||||
/// version.
|
/// version.
|
||||||
pub fn force_allocation_maybe_sized(
|
pub fn force_allocation_maybe_sized(
|
||||||
&mut self,
|
&mut self,
|
||||||
place: PlaceTy<'tcx, M::PointerTag>,
|
place: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
meta: MemPlaceMeta<M::PointerTag>,
|
meta: MemPlaceMeta<M::PointerTag>,
|
||||||
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, Option<Size>)> {
|
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, Option<Size>)> {
|
||||||
let (mplace, size) = match place.place {
|
let (mplace, size) = match place.place {
|
||||||
|
@ -1025,7 +1025,7 @@ where
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn force_allocation(
|
pub fn force_allocation(
|
||||||
&mut self,
|
&mut self,
|
||||||
place: PlaceTy<'tcx, M::PointerTag>,
|
place: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||||
Ok(self.force_allocation_maybe_sized(place, MemPlaceMeta::None)?.0)
|
Ok(self.force_allocation_maybe_sized(place, MemPlaceMeta::None)?.0)
|
||||||
}
|
}
|
||||||
|
@ -1061,7 +1061,7 @@ where
|
||||||
pub fn write_discriminant(
|
pub fn write_discriminant(
|
||||||
&mut self,
|
&mut self,
|
||||||
variant_index: VariantIdx,
|
variant_index: VariantIdx,
|
||||||
dest: PlaceTy<'tcx, M::PointerTag>,
|
dest: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
// Layout computation excludes uninhabited variants from consideration
|
// Layout computation excludes uninhabited variants from consideration
|
||||||
// therefore there's no way to represent those variants in the given layout.
|
// 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_val = size.truncate(discr_val);
|
||||||
|
|
||||||
let tag_dest = self.place_field(dest, tag_field)?;
|
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 {
|
Variants::Multiple {
|
||||||
tag_encoding:
|
tag_encoding:
|
||||||
|
@ -1123,7 +1123,7 @@ where
|
||||||
)?;
|
)?;
|
||||||
// Write result.
|
// Write result.
|
||||||
let niche_dest = self.place_field(dest, tag_field)?;
|
let niche_dest = self.place_field(dest, tag_field)?;
|
||||||
self.write_immediate(*tag_val, niche_dest)?;
|
self.write_immediate(*tag_val, &niche_dest)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
SetDiscriminant { place, variant_index } => {
|
SetDiscriminant { place, variant_index } => {
|
||||||
let dest = self.eval_place(**place)?;
|
let dest = self.eval_place(**place)?;
|
||||||
self.write_discriminant(*variant_index, dest)?;
|
self.write_discriminant(*variant_index, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark locals as alive
|
// Mark locals as alive
|
||||||
|
@ -110,7 +110,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Stacked Borrows.
|
// Stacked Borrows.
|
||||||
Retag(kind, place) => {
|
Retag(kind, place) => {
|
||||||
let dest = self.eval_place(**place)?;
|
let dest = self.eval_place(**place)?;
|
||||||
M::retag(self, *kind, dest)?;
|
M::retag(self, *kind, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Statements we do not track.
|
// Statements we do not track.
|
||||||
|
@ -156,13 +156,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
ThreadLocalRef(did) => {
|
ThreadLocalRef(did) => {
|
||||||
let id = M::thread_local_static_alloc_id(self, did)?;
|
let id = M::thread_local_static_alloc_id(self, did)?;
|
||||||
let val = self.global_base_pointer(id.into())?;
|
let val = self.global_base_pointer(id.into())?;
|
||||||
self.write_scalar(val, dest)?;
|
self.write_scalar(val, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Use(ref operand) => {
|
Use(ref operand) => {
|
||||||
// Avoid recomputing the layout
|
// Avoid recomputing the layout
|
||||||
let op = self.eval_operand(operand, Some(dest.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) => {
|
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 left = self.read_immediate(&self.eval_operand(left, layout)?)?;
|
||||||
let layout = binop_right_homogeneous(bin_op).then_some(left.layout);
|
let layout = binop_right_homogeneous(bin_op).then_some(left.layout);
|
||||||
let right = self.read_immediate(&self.eval_operand(right, 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) => {
|
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 left = self.read_immediate(&self.eval_operand(left, None)?)?;
|
||||||
let layout = binop_right_homogeneous(bin_op).then_some(left.layout);
|
let layout = binop_right_homogeneous(bin_op).then_some(left.layout);
|
||||||
let right = self.read_immediate(&self.eval_operand(right, 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) => {
|
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.read_immediate(&self.eval_operand(operand, Some(dest.layout))?)?;
|
||||||
let val = self.unary_op(un_op, &val)?;
|
let val = self.unary_op(un_op, &val)?;
|
||||||
assert_eq!(val.layout, dest.layout, "layout mismatch for result of {:?}", un_op);
|
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) => {
|
Aggregate(ref kind, ref operands) => {
|
||||||
let (dest, active_field_index) = match **kind {
|
let (dest, active_field_index) = match **kind {
|
||||||
mir::AggregateKind::Adt(adt_def, variant_index, _, _, active_field_index) => {
|
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() {
|
if adt_def.is_enum() {
|
||||||
(self.place_downcast(dest, variant_index)?, active_field_index)
|
(self.place_downcast(&dest, variant_index)?, active_field_index)
|
||||||
} else {
|
} else {
|
||||||
(dest, active_field_index)
|
(dest, active_field_index)
|
||||||
}
|
}
|
||||||
|
@ -207,21 +207,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Ignore zero-sized fields.
|
// Ignore zero-sized fields.
|
||||||
if !op.layout.is_zst() {
|
if !op.layout.is_zst() {
|
||||||
let field_index = active_field_index.unwrap_or(i);
|
let field_index = active_field_index.unwrap_or(i);
|
||||||
let field_dest = self.place_field(dest, field_index)?;
|
let field_dest = self.place_field(&dest, field_index)?;
|
||||||
self.copy_op(&op, field_dest)?;
|
self.copy_op(&op, &field_dest)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Repeat(ref operand, _) => {
|
Repeat(ref operand, _) => {
|
||||||
let op = self.eval_operand(operand, None)?;
|
let op = self.eval_operand(operand, None)?;
|
||||||
let dest = self.force_allocation(dest)?;
|
let dest = self.force_allocation(&dest)?;
|
||||||
let length = dest.len(self)?;
|
let length = dest.len(self)?;
|
||||||
|
|
||||||
if let Some(first_ptr) = self.check_mplace_access(dest, None)? {
|
if let Some(first_ptr) = self.check_mplace_access(dest, None)? {
|
||||||
// Write the first.
|
// Write the first.
|
||||||
let first = self.mplace_field(dest, 0)?;
|
let first = self.mplace_field(dest, 0)?;
|
||||||
self.copy_op(&op, first.into())?;
|
self.copy_op(&op, &first.into())?;
|
||||||
|
|
||||||
if length > 1 {
|
if length > 1 {
|
||||||
let elem_size = first.layout.size;
|
let elem_size = first.layout.size;
|
||||||
|
@ -242,23 +242,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
Len(place) => {
|
Len(place) => {
|
||||||
// FIXME(CTFE): don't allow computing the length of arrays in const eval
|
// FIXME(CTFE): don't allow computing the length of arrays in const eval
|
||||||
let src = self.eval_place(place)?;
|
let src = self.eval_place(place)?;
|
||||||
let mplace = self.force_allocation(src)?;
|
let mplace = self.force_allocation(&src)?;
|
||||||
let len = mplace.len(self)?;
|
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) => {
|
AddressOf(_, place) | Ref(_, _, place) => {
|
||||||
let src = self.eval_place(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 {
|
if place.layout.size.bytes() > 0 {
|
||||||
// definitely not a ZST
|
// definitely not a ZST
|
||||||
assert!(place.ptr.is_ptr(), "non-ZST places should be normalized to `Pointer`");
|
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, _) => {
|
NullaryOp(mir::NullOp::Box, _) => {
|
||||||
M::box_alloc(self, dest)?;
|
M::box_alloc(self, &dest)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
NullaryOp(mir::NullOp::SizeOf, ty) => {
|
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));
|
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) => {
|
Cast(cast_kind, ref operand, cast_ty) => {
|
||||||
let src = self.eval_operand(operand, None)?;
|
let src = self.eval_operand(operand, None)?;
|
||||||
let cast_ty = self.subst_from_current_frame_and_normalize_erasing_regions(cast_ty);
|
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) => {
|
Discriminant(place) => {
|
||||||
let op = self.eval_place_to_op(place, None)?;
|
let op = self.eval_place_to_op(place, None)?;
|
||||||
let discr_val = self.read_discriminant(&op)?.0;
|
let discr_val = self.read_discriminant(&op)?.0;
|
||||||
self.write_scalar(discr_val, dest)?;
|
self.write_scalar(discr_val, &dest)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let args = self.eval_operands(args)?;
|
let args = self.eval_operands(args)?;
|
||||||
|
let dest_place;
|
||||||
let ret = match destination {
|
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,
|
None => None,
|
||||||
};
|
};
|
||||||
self.eval_fn_call(fn_val, abi, &args[..], ret, *cleanup)?;
|
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);
|
trace!("TerminatorKind::drop: {:?}, type {}", place, ty);
|
||||||
|
|
||||||
let instance = Instance::resolve_drop_in_place(*self.tcx, 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 } => {
|
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,
|
&mut self,
|
||||||
rust_abi: bool,
|
rust_abi: bool,
|
||||||
caller_arg: &mut impl Iterator<Item = OpTy<'tcx, M::PointerTag>>,
|
caller_arg: &mut impl Iterator<Item = OpTy<'tcx, M::PointerTag>>,
|
||||||
callee_arg: PlaceTy<'tcx, M::PointerTag>,
|
callee_arg: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
if rust_abi && callee_arg.layout.is_zst() {
|
if rust_abi && callee_arg.layout.is_zst() {
|
||||||
// Nothing to do.
|
// 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>,
|
fn_val: FnVal<'tcx, M::ExtraFnVal>,
|
||||||
caller_abi: Abi,
|
caller_abi: Abi,
|
||||||
args: &[OpTy<'tcx, M::PointerTag>],
|
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>,
|
unwind: Option<mir::BasicBlock>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
trace!("eval_fn_call: {:#?}", fn_val);
|
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 {
|
if Some(local) == body.spread_arg {
|
||||||
// Must be a tuple
|
// Must be a tuple
|
||||||
for i in 0..dest.layout.fields.count() {
|
for i in 0..dest.layout.fields.count() {
|
||||||
let dest = self.place_field(dest, i)?;
|
let dest = self.place_field(&dest, i)?;
|
||||||
self.pass_argument(rust_abi, &mut caller_iter, dest)?;
|
self.pass_argument(rust_abi, &mut caller_iter, &dest)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Normal argument
|
// 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
|
// 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(
|
fn drop_in_place(
|
||||||
&mut self,
|
&mut self,
|
||||||
place: PlaceTy<'tcx, M::PointerTag>,
|
place: &PlaceTy<'tcx, M::PointerTag>,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
target: mir::BasicBlock,
|
target: mir::BasicBlock,
|
||||||
unwind: Option<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),
|
FnVal::Instance(instance),
|
||||||
Abi::Rust,
|
Abi::Rust,
|
||||||
&[arg.into()],
|
&[arg.into()],
|
||||||
Some((dest.into(), target)),
|
Some((&dest.into(), target)),
|
||||||
unwind,
|
unwind,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
|
||||||
_instance: ty::Instance<'tcx>,
|
_instance: ty::Instance<'tcx>,
|
||||||
_abi: Abi,
|
_abi: Abi,
|
||||||
_args: &[OpTy<'tcx>],
|
_args: &[OpTy<'tcx>],
|
||||||
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
|
_ret: Option<(&PlaceTy<'tcx>, BasicBlock)>,
|
||||||
_unwind: Option<BasicBlock>,
|
_unwind: Option<BasicBlock>,
|
||||||
) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> {
|
) -> InterpResult<'tcx, Option<&'mir Body<'tcx>>> {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -207,7 +207,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine<'mir, 'tcx>
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_instance: ty::Instance<'tcx>,
|
_instance: ty::Instance<'tcx>,
|
||||||
_args: &[OpTy<'tcx>],
|
_args: &[OpTy<'tcx>],
|
||||||
_ret: Option<(PlaceTy<'tcx>, BasicBlock)>,
|
_ret: Option<(&PlaceTy<'tcx>, BasicBlock)>,
|
||||||
_unwind: Option<BasicBlock>,
|
_unwind: Option<BasicBlock>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
throw_machine_stop_str!("calling intrinsics isn't supported in ConstProp")
|
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(
|
fn box_alloc(
|
||||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||||
_dest: PlaceTy<'tcx>,
|
_dest: &PlaceTy<'tcx>,
|
||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
throw_machine_stop_str!("can't const prop heap allocations")
|
throw_machine_stop_str!("can't const prop heap allocations")
|
||||||
}
|
}
|
||||||
|
@ -392,12 +392,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
.filter(|ret_layout| {
|
.filter(|ret_layout| {
|
||||||
!ret_layout.is_zst() && ret_layout.size < Size::from_bytes(MAX_ALLOC_LIMIT)
|
!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(
|
ecx.push_stack_frame(
|
||||||
Instance::new(def_id, substs),
|
Instance::new(def_id, substs),
|
||||||
dummy_body,
|
dummy_body,
|
||||||
ret.map(Into::into),
|
ret.as_ref(),
|
||||||
StackPopCleanup::None { cleanup: false },
|
StackPopCleanup::None { cleanup: false },
|
||||||
)
|
)
|
||||||
.expect("failed to push initial stack frame");
|
.expect("failed to push initial stack frame");
|
||||||
|
@ -760,14 +760,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
match op {
|
match op {
|
||||||
BinOp::BitAnd => {
|
BinOp::BitAnd => {
|
||||||
if arg_value == 0 {
|
if arg_value == 0 {
|
||||||
this.ecx.write_immediate(*const_arg, dest)?;
|
this.ecx.write_immediate(*const_arg, &dest)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BinOp::BitOr => {
|
BinOp::BitOr => {
|
||||||
if arg_value == const_arg.layout.size.truncate(u128::MAX)
|
if arg_value == const_arg.layout.size.truncate(u128::MAX)
|
||||||
|| (const_arg.layout.ty.is_bool() && arg_value == 1)
|
|| (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 => {
|
BinOp::Mul => {
|
||||||
|
@ -777,9 +777,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
|
||||||
const_arg.to_scalar()?.into(),
|
const_arg.to_scalar()?.into(),
|
||||||
Scalar::from_bool(false).into(),
|
Scalar::from_bool(false).into(),
|
||||||
);
|
);
|
||||||
this.ecx.write_immediate(val, dest)?;
|
this.ecx.write_immediate(val, &dest)?;
|
||||||
} else {
|
} else {
|
||||||
this.ecx.write_immediate(*const_arg, dest)?;
|
this.ecx.write_immediate(*const_arg, &dest)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue