interpret: make Writeable trait about a to_place operation
This commit is contained in:
parent
fa60ea7d38
commit
8ad808db7e
@ -691,7 +691,7 @@ pub fn place_to_op(
|
||||
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
|
||||
match place.as_mplace_or_local() {
|
||||
Left(mplace) => Ok(mplace.into()),
|
||||
Right((local, offset, locals_addr)) => {
|
||||
Right((local, offset, locals_addr, _)) => {
|
||||
debug_assert!(place.layout.is_sized()); // only sized locals can ever be `Place::Local`.
|
||||
debug_assert_eq!(locals_addr, self.frame().locals_addr());
|
||||
let base = self.local_to_op(local, None)?;
|
||||
|
@ -231,10 +231,12 @@ pub(super) fn place(&self) -> &Place<Prov> {
|
||||
#[inline(always)]
|
||||
pub fn as_mplace_or_local(
|
||||
&self,
|
||||
) -> Either<MPlaceTy<'tcx, Prov>, (mir::Local, Option<Size>, usize)> {
|
||||
) -> Either<MPlaceTy<'tcx, Prov>, (mir::Local, Option<Size>, usize, TyAndLayout<'tcx>)> {
|
||||
match self.place {
|
||||
Place::Ptr(mplace) => Left(MPlaceTy { mplace, layout: self.layout }),
|
||||
Place::Local { local, offset, locals_addr } => Right((local, offset, locals_addr)),
|
||||
Place::Local { local, offset, locals_addr } => {
|
||||
Right((local, offset, locals_addr, self.layout))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -277,7 +279,7 @@ fn offset_with_meta<M: Machine<'tcx, Provenance = Prov>>(
|
||||
) -> InterpResult<'tcx, Self> {
|
||||
Ok(match self.as_mplace_or_local() {
|
||||
Left(mplace) => mplace.offset_with_meta(offset, mode, meta, layout, ecx)?.into(),
|
||||
Right((local, old_offset, locals_addr)) => {
|
||||
Right((local, old_offset, locals_addr, _)) => {
|
||||
debug_assert!(layout.is_sized(), "unsized locals should live in memory");
|
||||
assert_matches!(meta, MemPlaceMeta::None); // we couldn't store it anyway...
|
||||
// `Place::Local` are always in-bounds of their surrounding local, so we can just
|
||||
@ -328,9 +330,7 @@ pub fn assert_mem_place(&self) -> MPlaceTy<'tcx, Prov> {
|
||||
|
||||
/// The `Weiteable` trait describes interpreter values that can be written to.
|
||||
pub trait Writeable<'tcx, Prov: Provenance>: Projectable<'tcx, Prov> {
|
||||
fn as_mplace_or_local(
|
||||
&self,
|
||||
) -> Either<MPlaceTy<'tcx, Prov>, (mir::Local, Option<Size>, usize, TyAndLayout<'tcx>)>;
|
||||
fn to_place(&self) -> PlaceTy<'tcx, Prov>;
|
||||
|
||||
fn force_mplace<M: Machine<'tcx, Provenance = Prov>>(
|
||||
&self,
|
||||
@ -340,11 +340,8 @@ fn force_mplace<M: Machine<'tcx, Provenance = Prov>>(
|
||||
|
||||
impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for PlaceTy<'tcx, Prov> {
|
||||
#[inline(always)]
|
||||
fn as_mplace_or_local(
|
||||
&self,
|
||||
) -> Either<MPlaceTy<'tcx, Prov>, (mir::Local, Option<Size>, usize, TyAndLayout<'tcx>)> {
|
||||
self.as_mplace_or_local()
|
||||
.map_right(|(local, offset, locals_addr)| (local, offset, locals_addr, self.layout))
|
||||
fn to_place(&self) -> PlaceTy<'tcx, Prov> {
|
||||
self.clone()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -358,10 +355,8 @@ fn force_mplace<M: Machine<'tcx, Provenance = Prov>>(
|
||||
|
||||
impl<'tcx, Prov: Provenance> Writeable<'tcx, Prov> for MPlaceTy<'tcx, Prov> {
|
||||
#[inline(always)]
|
||||
fn as_mplace_or_local(
|
||||
&self,
|
||||
) -> Either<MPlaceTy<'tcx, Prov>, (mir::Local, Option<Size>, usize, TyAndLayout<'tcx>)> {
|
||||
Left(self.clone())
|
||||
fn to_place(&self) -> PlaceTy<'tcx, Prov> {
|
||||
self.clone().into()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -615,7 +610,7 @@ fn write_immediate_no_validate(
|
||||
|
||||
// See if we can avoid an allocation. This is the counterpart to `read_immediate_raw`,
|
||||
// but not factored as a separate function.
|
||||
let mplace = match dest.as_mplace_or_local() {
|
||||
let mplace = match dest.to_place().as_mplace_or_local() {
|
||||
Right((local, offset, locals_addr, layout)) => {
|
||||
if offset.is_some() {
|
||||
// This has been projected to a part of this local. We could have complicated
|
||||
@ -728,7 +723,7 @@ pub fn write_uninit(
|
||||
&mut self,
|
||||
dest: &impl Writeable<'tcx, M::Provenance>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let mplace = match dest.as_mplace_or_local() {
|
||||
let mplace = match dest.to_place().as_mplace_or_local() {
|
||||
Left(mplace) => mplace,
|
||||
Right((local, offset, locals_addr, layout)) => {
|
||||
if offset.is_some() {
|
||||
|
Loading…
Reference in New Issue
Block a user