deduplicate a lot of code
This commit is contained in:
parent
28af967bb9
commit
bc698c73e9
6 changed files with 119 additions and 244 deletions
|
@ -2,16 +2,16 @@ use super::eval_queries::{mk_eval_cx, op_to_const};
|
|||
use super::machine::CompileTimeEvalContext;
|
||||
use crate::interpret::{
|
||||
intern_const_alloc_recursive, ConstValue, ImmTy, Immediate, InternKind, MemoryKind, PlaceTy,
|
||||
Pointer, Scalar, ScalarMaybeUninit,
|
||||
Scalar, ScalarMaybeUninit,
|
||||
};
|
||||
use rustc_middle::mir::interpret::{ConstAlloc, GlobalAlloc};
|
||||
use rustc_middle::mir::interpret::ConstAlloc;
|
||||
use rustc_middle::mir::{Field, ProjectionElem};
|
||||
use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt};
|
||||
use rustc_span::source_map::DUMMY_SP;
|
||||
use rustc_target::abi::VariantIdx;
|
||||
|
||||
use crate::interpret::visitor::Value;
|
||||
use crate::interpret::MPlaceTy;
|
||||
use crate::interpret::Value;
|
||||
|
||||
/// Convert an evaluated constant to a type level constant
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
|
@ -54,6 +54,7 @@ fn branches<'tcx>(
|
|||
Some(ty::ValTree::Branch(ecx.tcx.arena.alloc_from_iter(branches.collect::<Option<Vec<_>>>()?)))
|
||||
}
|
||||
|
||||
#[instrument(skip(ecx), level = "debug")]
|
||||
fn slice_branches<'tcx>(
|
||||
ecx: &CompileTimeEvalContext<'tcx, 'tcx>,
|
||||
place: &MPlaceTy<'tcx>,
|
||||
|
@ -139,15 +140,44 @@ fn const_to_valtree_inner<'tcx>(
|
|||
#[instrument(skip(ecx), level = "debug")]
|
||||
fn create_mplace_from_layout<'tcx>(
|
||||
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>,
|
||||
param_env_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
|
||||
ty: Ty<'tcx>,
|
||||
) -> MPlaceTy<'tcx> {
|
||||
let tcx = ecx.tcx;
|
||||
let layout = tcx.layout_of(param_env_ty).unwrap();
|
||||
let param_env = ecx.param_env;
|
||||
let layout = tcx.layout_of(param_env.and(ty)).unwrap();
|
||||
debug!(?layout);
|
||||
|
||||
ecx.allocate(layout, MemoryKind::Stack).unwrap()
|
||||
}
|
||||
|
||||
#[instrument(skip(ecx), level = "debug")]
|
||||
fn create_pointee_place<'tcx>(
|
||||
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
valtree: ty::ValTree<'tcx>,
|
||||
) -> MPlaceTy<'tcx> {
|
||||
let tcx = ecx.tcx.tcx;
|
||||
|
||||
match ty.kind() {
|
||||
ty::Slice(_) | ty::Str => {
|
||||
let slice_ty = match ty.kind() {
|
||||
ty::Slice(slice_ty) => *slice_ty,
|
||||
ty::Str => tcx.mk_ty(ty::Uint(ty::UintTy::U8)),
|
||||
_ => bug!("expected ty::Slice | ty::Str"),
|
||||
};
|
||||
|
||||
// Create a place for the underlying array
|
||||
let len = valtree.unwrap_branch().len() as u64;
|
||||
let arr_ty = tcx.mk_array(slice_ty, len as u64);
|
||||
let place = create_mplace_from_layout(ecx, arr_ty);
|
||||
debug!(?place);
|
||||
|
||||
place
|
||||
}
|
||||
_ => create_mplace_from_layout(ecx, ty),
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a `ValTree` to a `ConstValue`, which is needed after mir
|
||||
/// construction has finished.
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
|
@ -174,96 +204,28 @@ pub fn valtree_to_const_value<'tcx>(
|
|||
),
|
||||
},
|
||||
ty::Ref(_, inner_ty, _) => {
|
||||
match inner_ty.kind() {
|
||||
ty::Slice(_) | ty::Str => {
|
||||
let slice_ty = match inner_ty.kind() {
|
||||
ty::Slice(slice_ty) => *slice_ty,
|
||||
ty::Str => tcx.mk_ty(ty::Uint(ty::UintTy::U8)),
|
||||
_ => bug!("expected ty::Slice | ty::Str"),
|
||||
};
|
||||
debug!(?slice_ty);
|
||||
// create a place for the pointee
|
||||
let mut pointee_place = create_pointee_place(&mut ecx, *inner_ty, valtree);
|
||||
debug!(?pointee_place);
|
||||
|
||||
let valtrees = valtree.unwrap_branch();
|
||||
// insert elements of valtree into `place`
|
||||
fill_place_recursively(&mut ecx, &mut pointee_place, valtree);
|
||||
dump_place(&ecx, pointee_place.into());
|
||||
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &pointee_place).unwrap();
|
||||
|
||||
// Create a place for the underlying array
|
||||
let len = valtrees.len();
|
||||
let arr_ty = tcx.mk_array(slice_ty, len as u64);
|
||||
let mut place =
|
||||
create_mplace_from_layout(&mut ecx, ty::ParamEnv::empty().and(arr_ty));
|
||||
debug!(?place);
|
||||
let ref_place = pointee_place.to_ref(&tcx);
|
||||
let imm = ImmTy::from_immediate(ref_place, tcx.layout_of(param_env_ty).unwrap());
|
||||
|
||||
// Insert elements of `arr_valtree` into `place`
|
||||
fill_place_recursively(&mut ecx, &mut place, valtree, arr_ty);
|
||||
dump_place(&ecx, place.into());
|
||||
let const_val = op_to_const(&ecx, &imm.into());
|
||||
debug!(?const_val);
|
||||
|
||||
// The allocation behind `place` is local, we need to intern it
|
||||
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
|
||||
|
||||
// Now we need to get the Allocation
|
||||
let alloc_id = place.mplace.ptr.provenance.unwrap();
|
||||
debug!(?alloc_id);
|
||||
|
||||
let data = match tcx.get_global_alloc(alloc_id) {
|
||||
Some(GlobalAlloc::Memory(const_alloc)) => const_alloc,
|
||||
_ => bug!("expected memory allocation"),
|
||||
};
|
||||
debug!(?data);
|
||||
|
||||
return ConstValue::Slice { data, start: 0, end: len as usize };
|
||||
}
|
||||
_ => {
|
||||
match valtree {
|
||||
ty::ValTree::Branch(_) => {
|
||||
// create a place for the pointee
|
||||
let mut place = create_mplace_from_layout(
|
||||
&mut ecx,
|
||||
ty::ParamEnv::empty().and(*inner_ty),
|
||||
);
|
||||
debug!(?place);
|
||||
|
||||
// insert elements of valtree into `place`
|
||||
fill_place_recursively(&mut ecx, &mut place, valtree, *inner_ty);
|
||||
dump_place(&ecx, place.into());
|
||||
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place)
|
||||
.unwrap();
|
||||
|
||||
let ref_place = place.mplace.to_ref(&tcx);
|
||||
let imm = ImmTy::from_immediate(
|
||||
ref_place,
|
||||
tcx.layout_of(param_env_ty).unwrap(),
|
||||
);
|
||||
|
||||
let const_val = op_to_const(&ecx, &imm.into());
|
||||
debug!(?const_val);
|
||||
|
||||
const_val
|
||||
}
|
||||
ty::ValTree::Leaf(_) => {
|
||||
let mut place = create_mplace_from_layout(
|
||||
&mut ecx,
|
||||
ty::ParamEnv::empty().and(*inner_ty),
|
||||
);
|
||||
|
||||
fill_place_recursively(&mut ecx, &mut place, valtree, *inner_ty);
|
||||
dump_place(&ecx, place.into());
|
||||
|
||||
let ref_place = place.mplace.to_ref(&tcx);
|
||||
let imm = ImmTy::from_immediate(
|
||||
ref_place,
|
||||
tcx.layout_of(param_env_ty).unwrap(),
|
||||
);
|
||||
|
||||
op_to_const(&ecx, &imm.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const_val
|
||||
}
|
||||
ty::Tuple(_) | ty::Array(_, _) | ty::Adt(..) => {
|
||||
let mut place = create_mplace_from_layout(&mut ecx, param_env_ty);
|
||||
let mut place = create_mplace_from_layout(&mut ecx, ty);
|
||||
debug!(?place);
|
||||
|
||||
fill_place_recursively(&mut ecx, &mut place, valtree, ty);
|
||||
fill_place_recursively(&mut ecx, &mut place, valtree);
|
||||
dump_place(&ecx, place.into());
|
||||
intern_const_alloc_recursive(&mut ecx, InternKind::Constant, &place).unwrap();
|
||||
|
||||
|
@ -301,12 +263,12 @@ fn fill_place_recursively<'tcx>(
|
|||
ecx: &mut CompileTimeEvalContext<'tcx, 'tcx>,
|
||||
place: &mut MPlaceTy<'tcx>,
|
||||
valtree: ty::ValTree<'tcx>,
|
||||
ty: Ty<'tcx>,
|
||||
) {
|
||||
// This will match on valtree and write the value(s) corresponding to the ValTree
|
||||
// inside the place recursively.
|
||||
|
||||
let tcx = ecx.tcx.tcx;
|
||||
let ty = place.layout.ty;
|
||||
|
||||
match ty.kind() {
|
||||
ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => {
|
||||
|
@ -319,161 +281,90 @@ fn fill_place_recursively<'tcx>(
|
|||
.unwrap();
|
||||
}
|
||||
ty::Ref(_, inner_ty, _) => {
|
||||
match inner_ty.kind() {
|
||||
let mut pointee_place = create_pointee_place(ecx, *inner_ty, valtree);
|
||||
debug!(?pointee_place);
|
||||
|
||||
fill_place_recursively(ecx, &mut pointee_place, valtree);
|
||||
dump_place(ecx, pointee_place.into());
|
||||
intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap();
|
||||
|
||||
let imm = match inner_ty.kind() {
|
||||
ty::Slice(_) | ty::Str => {
|
||||
let slice_ty = match inner_ty.kind() {
|
||||
ty::Slice(slice_ty) => *slice_ty,
|
||||
ty::Str => tcx.mk_ty(ty::Uint(ty::UintTy::U8)),
|
||||
_ => bug!("expected ty::Slice | ty::Str"),
|
||||
};
|
||||
debug!(?slice_ty);
|
||||
|
||||
let valtrees = valtree.unwrap_branch();
|
||||
debug!(?valtrees);
|
||||
let len = valtrees.len();
|
||||
debug!(?len);
|
||||
|
||||
// create a place for the underlying array
|
||||
let arr_ty = tcx.mk_array(slice_ty, len as u64);
|
||||
let mut arr_place =
|
||||
create_mplace_from_layout(ecx, ty::ParamEnv::empty().and(arr_ty));
|
||||
debug!(?arr_place);
|
||||
|
||||
// Insert elements of `arr_valtree` into `place`
|
||||
fill_place_recursively(ecx, &mut arr_place, valtree, arr_ty);
|
||||
dump_place(&ecx, arr_place.into());
|
||||
|
||||
// Now we need to create a `ScalarPair` from the filled `place`
|
||||
// and write that into `place`
|
||||
let (alloc_id, offset) = arr_place.mplace.ptr.into_parts();
|
||||
debug!(?alloc_id, ?offset);
|
||||
let unwrapped_ptr = Pointer { offset, provenance: alloc_id.unwrap() };
|
||||
let len = valtree.unwrap_branch().len();
|
||||
let len_scalar = ScalarMaybeUninit::Scalar(Scalar::from_u64(len as u64));
|
||||
|
||||
let imm = Immediate::ScalarPair(
|
||||
ScalarMaybeUninit::from_pointer(unwrapped_ptr, &tcx),
|
||||
Immediate::ScalarPair(
|
||||
ScalarMaybeUninit::from_maybe_pointer((*pointee_place).ptr, &tcx),
|
||||
len_scalar,
|
||||
);
|
||||
debug!(?imm);
|
||||
|
||||
// Now write the ScalarPair into the original place we wanted to fill
|
||||
// in this call
|
||||
let _ = ecx.write_immediate(imm, &(*place).into()).unwrap();
|
||||
|
||||
dump_place(&ecx, (*place).into());
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let mut pointee_place =
|
||||
create_mplace_from_layout(ecx, ty::ParamEnv::empty().and(*inner_ty));
|
||||
debug!(?pointee_place);
|
||||
fill_place_recursively(ecx, &mut pointee_place, valtree, *inner_ty);
|
||||
_ => pointee_place.to_ref(&tcx),
|
||||
};
|
||||
debug!(?imm);
|
||||
|
||||
dump_place(ecx, pointee_place.into());
|
||||
intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place)
|
||||
.unwrap();
|
||||
|
||||
let imm = pointee_place.mplace.to_ref(&tcx);
|
||||
debug!(?imm);
|
||||
|
||||
ecx.write_immediate(imm, &(*place).into()).unwrap();
|
||||
}
|
||||
}
|
||||
ecx.write_immediate(imm, &(*place).into()).unwrap();
|
||||
}
|
||||
ty::Tuple(tuple_types) => {
|
||||
ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str => {
|
||||
let branches = valtree.unwrap_branch();
|
||||
assert_eq!(tuple_types.len(), branches.len());
|
||||
|
||||
// Need to downcast place for enums
|
||||
let (place_adjusted, branches, variant_idx) = match ty.kind() {
|
||||
ty::Adt(def, _) if def.is_enum() => {
|
||||
// First element of valtree corresponds to variant
|
||||
let scalar_int = branches[0].unwrap_leaf();
|
||||
let variant_idx = VariantIdx::from_u32(scalar_int.try_to_u32().unwrap());
|
||||
let variant = def.variant(variant_idx);
|
||||
debug!(?variant);
|
||||
|
||||
(
|
||||
place.project_downcast(ecx, variant_idx).unwrap(),
|
||||
&branches[1..],
|
||||
Some(variant_idx),
|
||||
)
|
||||
}
|
||||
_ => (*place, branches, None),
|
||||
};
|
||||
debug!(?place_adjusted, ?branches);
|
||||
|
||||
// Create the places for the fields and fill them recursively
|
||||
for (i, inner_valtree) in branches.iter().enumerate() {
|
||||
debug!(?i, ?inner_valtree);
|
||||
let inner_ty = tuple_types.get(i).expect(&format!(
|
||||
"expected to be able to index at position {} into {:?}",
|
||||
i, tuple_types
|
||||
));
|
||||
debug!(?inner_ty);
|
||||
|
||||
// Create the mplace for the tuple element
|
||||
let mut place_inner = ecx.mplace_field(place, i).unwrap();
|
||||
let mut place_inner = match *ty.kind() {
|
||||
ty::Adt(def, substs) if !def.is_enum() => {
|
||||
let field = &def.variant(VariantIdx::from_usize(0)).fields[i];
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
let projection_elem = ProjectionElem::Field(Field::from_usize(i), field_ty);
|
||||
|
||||
ecx.mplace_projection(&place_adjusted, projection_elem).unwrap()
|
||||
}
|
||||
ty::Adt(_, _) | ty::Tuple(_) => ecx.mplace_field(&place_adjusted, i).unwrap(),
|
||||
ty::Array(_, _) | ty::Str => {
|
||||
ecx.mplace_index(&place_adjusted, i as u64).unwrap()
|
||||
}
|
||||
_ => bug!(),
|
||||
};
|
||||
debug!(?place_inner);
|
||||
|
||||
// insert valtree corresponding to tuple element into place
|
||||
fill_place_recursively(ecx, &mut place_inner, *inner_valtree, *inner_ty);
|
||||
}
|
||||
}
|
||||
ty::Array(inner_ty, _) => {
|
||||
let inner_valtrees = valtree.unwrap_branch();
|
||||
for (i, inner_valtree) in inner_valtrees.iter().enumerate() {
|
||||
debug!(?i, ?inner_valtree);
|
||||
|
||||
let mut place_inner = ecx.mplace_field(place, i).unwrap();
|
||||
debug!(?place_inner);
|
||||
|
||||
fill_place_recursively(ecx, &mut place_inner, *inner_valtree, *inner_ty)
|
||||
}
|
||||
}
|
||||
ty::Adt(def, substs) if def.is_enum() => {
|
||||
debug!("enum, substs: {:?}", substs);
|
||||
let inner_valtrees = valtree.unwrap_branch();
|
||||
|
||||
// First element of valtree corresponds to variant
|
||||
let scalar_int = inner_valtrees[0].unwrap_leaf();
|
||||
let variant_idx = VariantIdx::from_u32(scalar_int.try_to_u32().unwrap());
|
||||
let variant = def.variant(variant_idx);
|
||||
debug!(?variant);
|
||||
|
||||
// Need to downcast place
|
||||
let place_downcast = place.project_downcast(ecx, variant_idx).unwrap();
|
||||
debug!(?place_downcast);
|
||||
|
||||
// fill `place_downcast` with the valtree elements corresponding to
|
||||
// the fields of the enum
|
||||
let fields = &variant.fields;
|
||||
let inner_valtrees = &inner_valtrees[1..];
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
debug!(?i, ?field);
|
||||
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
debug!(?field_ty);
|
||||
|
||||
let mut field_mplace = ecx.mplace_field(&place_downcast, i).unwrap();
|
||||
debug!(?field_mplace);
|
||||
let inner_valtree = inner_valtrees[i];
|
||||
|
||||
fill_place_recursively(ecx, &mut field_mplace, inner_valtree, field_ty);
|
||||
dump_place(&ecx, field_mplace.into());
|
||||
fill_place_recursively(ecx, &mut place_inner, *inner_valtree);
|
||||
dump_place(&ecx, place_inner.into());
|
||||
}
|
||||
|
||||
debug!("dump of place_downcast");
|
||||
dump_place(ecx, place_downcast.into());
|
||||
debug!("dump of place_adjusted:");
|
||||
dump_place(ecx, place_adjusted.into());
|
||||
|
||||
if let Some(variant_idx) = variant_idx {
|
||||
// don't forget filling the place with the discriminant of the enum
|
||||
ecx.write_discriminant(variant_idx, &(*place).into()).unwrap();
|
||||
}
|
||||
|
||||
// don't forget filling the place with the discriminant of the enum
|
||||
ecx.write_discriminant(variant_idx, &(*place).into()).unwrap();
|
||||
dump_place(ecx, (*place).into());
|
||||
}
|
||||
ty::Adt(def, substs) => {
|
||||
debug!("Adt def: {:?} with substs: {:?}", def, substs);
|
||||
let inner_valtrees = valtree.unwrap_branch();
|
||||
debug!(?inner_valtrees);
|
||||
let (fields, inner_valtrees) =
|
||||
(&def.variant(VariantIdx::from_usize(0)).fields[..], inner_valtrees);
|
||||
|
||||
debug!("fields: {:?}", fields);
|
||||
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
let field_ty = field.ty(tcx, substs);
|
||||
debug!(?field_ty);
|
||||
let old_field_ty = tcx.type_of(field.did);
|
||||
debug!(?old_field_ty);
|
||||
let projection_elem = ProjectionElem::Field(Field::from_usize(i), field_ty);
|
||||
let mut field_place = ecx.mplace_projection(place, projection_elem).unwrap();
|
||||
let inner_valtree = inner_valtrees[i];
|
||||
|
||||
fill_place_recursively(ecx, &mut field_place, inner_valtree, field_ty);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
_ => bug!("shouldn't have created a ValTree for {:?}", ty),
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_place<'tcx>(ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: PlaceTy<'tcx>) {
|
||||
trace!("{:?}", ecx.dump_place(place.place));
|
||||
trace!("{:?}", ecx.dump_place(*place));
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ mod terminator;
|
|||
mod traits;
|
||||
mod util;
|
||||
mod validity;
|
||||
pub(crate) mod visitor;
|
||||
mod visitor;
|
||||
|
||||
pub use rustc_middle::mir::interpret::*; // have all the `interpret` symbols in one place: here
|
||||
|
||||
|
@ -27,7 +27,7 @@ pub use self::memory::{AllocCheck, AllocRef, AllocRefMut, FnVal, Memory, MemoryK
|
|||
pub use self::operand::{ImmTy, Immediate, OpTy, Operand};
|
||||
pub use self::place::{MPlaceTy, MemPlace, MemPlaceMeta, Place, PlaceTy};
|
||||
pub use self::validity::{CtfeValidationMode, RefTracking};
|
||||
pub use self::visitor::{MutValueVisitor, ValueVisitor};
|
||||
pub use self::visitor::{MutValueVisitor, Value, ValueVisitor};
|
||||
|
||||
crate use self::intrinsics::eval_nullary_intrinsic;
|
||||
use eval_context::{from_known_layout, mir_assign_valid_types};
|
||||
|
|
|
@ -98,7 +98,7 @@ impl<'tcx, Tag: Provenance> Immediate<Tag> {
|
|||
// as input for binary and cast operations.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct ImmTy<'tcx, Tag: Provenance = AllocId> {
|
||||
pub imm: Immediate<Tag>,
|
||||
imm: Immediate<Tag>,
|
||||
pub layout: TyAndLayout<'tcx>,
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ impl<'tcx, Tag: Provenance> ImmTy<'tcx, Tag> {
|
|||
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
/// Try reading an immediate in memory; this is interesting particularly for `ScalarPair`.
|
||||
/// Returns `None` if the layout does not permit loading this as a value.
|
||||
pub(crate) fn try_read_immediate_from_mplace(
|
||||
fn try_read_immediate_from_mplace(
|
||||
&self,
|
||||
mplace: &MPlaceTy<'tcx, M::PointerTag>,
|
||||
) -> InterpResult<'tcx, Option<ImmTy<'tcx, M::PointerTag>>> {
|
||||
|
|
|
@ -82,7 +82,7 @@ rustc_data_structures::static_assert_size!(Place, 56);
|
|||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub struct PlaceTy<'tcx, Tag: Provenance = AllocId> {
|
||||
pub(crate) place: Place<Tag>, // Keep this private; it helps enforce invariants.
|
||||
place: Place<Tag>, // Keep this private; it helps enforce invariants.
|
||||
pub layout: TyAndLayout<'tcx>,
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ impl<'tcx, Tag: Provenance> std::ops::Deref for PlaceTy<'tcx, Tag> {
|
|||
/// A MemPlace with its layout. Constructing it is only possible in this module.
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug)]
|
||||
pub struct MPlaceTy<'tcx, Tag: Provenance = AllocId> {
|
||||
pub(crate) mplace: MemPlace<Tag>,
|
||||
mplace: MemPlace<Tag>,
|
||||
pub layout: TyAndLayout<'tcx>,
|
||||
}
|
||||
|
||||
|
@ -589,7 +589,6 @@ where
|
|||
}
|
||||
|
||||
/// Projects into a place.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn place_projection(
|
||||
&mut self,
|
||||
base: &PlaceTy<'tcx, M::PointerTag>,
|
||||
|
@ -626,18 +625,15 @@ where
|
|||
&mut self,
|
||||
place: mir::Place<'tcx>,
|
||||
) -> InterpResult<'tcx, PlaceTy<'tcx, M::PointerTag>> {
|
||||
debug!("projection: {:?}", place.projection);
|
||||
let mut place_ty = PlaceTy {
|
||||
// This works even for dead/uninitialized locals; we check further when writing
|
||||
place: Place::Local { frame: self.frame_idx(), local: place.local },
|
||||
layout: self.layout_of_local(self.frame(), place.local, None)?,
|
||||
};
|
||||
debug!(?place_ty);
|
||||
|
||||
for elem in place.projection.iter() {
|
||||
place_ty = self.place_projection(&place_ty, &elem)?
|
||||
}
|
||||
debug!("place after projections: {:?}", place_ty);
|
||||
|
||||
trace!("{:?}", self.dump_place(place_ty.place));
|
||||
// Sanity-check the type we ended up with.
|
||||
|
@ -693,7 +689,6 @@ where
|
|||
/// Write an immediate to a place.
|
||||
/// If you use this you are responsible for validating that things got copied at the
|
||||
/// right type.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn write_immediate_no_validate(
|
||||
&mut self,
|
||||
src: Immediate<M::PointerTag>,
|
||||
|
@ -746,7 +741,6 @@ where
|
|||
/// Write an immediate to memory.
|
||||
/// If you use this you are responsible for validating that things got copied at the
|
||||
/// right type.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn write_immediate_to_mplace_no_validate(
|
||||
&mut self,
|
||||
value: Immediate<M::PointerTag>,
|
||||
|
@ -769,7 +763,6 @@ where
|
|||
// cover all the bytes!
|
||||
match value {
|
||||
Immediate::Scalar(scalar) => {
|
||||
debug!(?scalar);
|
||||
match dest.layout.abi {
|
||||
Abi::Scalar(_) => {} // fine
|
||||
_ => span_bug!(
|
||||
|
@ -882,7 +875,6 @@ where
|
|||
// Let us see if the layout is simple so we take a shortcut, avoid force_allocation.
|
||||
let src = match self.try_read_immediate(src)? {
|
||||
Ok(src_val) => {
|
||||
debug!("immediate from src is {:?}", src_val);
|
||||
assert!(!src.layout.is_unsized(), "cannot have unsized immediates");
|
||||
// Yay, we got a value that we can write directly.
|
||||
// FIXME: Add a check to make sure that if `src` is indirect,
|
||||
|
@ -978,7 +970,6 @@ where
|
|||
) -> InterpResult<'tcx, (MPlaceTy<'tcx, M::PointerTag>, Option<Size>)> {
|
||||
let (mplace, size) = match place.place {
|
||||
Place::Local { frame, local } => {
|
||||
debug!("LocalPlace");
|
||||
match M::access_local_mut(self, frame, local)? {
|
||||
Ok(&mut local_val) => {
|
||||
// We need to make an allocation.
|
||||
|
@ -992,12 +983,9 @@ where
|
|||
let (size, align) = self
|
||||
.size_and_align_of(&meta, &local_layout)?
|
||||
.expect("Cannot allocate for non-dyn-sized type");
|
||||
debug!(?size, ?align);
|
||||
let ptr = self.allocate_ptr(size, align, MemoryKind::Stack)?;
|
||||
debug!("allocated ptr: {:?}", ptr);
|
||||
let mplace = MemPlace { ptr: ptr.into(), align, meta };
|
||||
if let LocalValue::Live(Operand::Immediate(value)) = local_val {
|
||||
debug!("LocalValue::Live: immediate value {:?}", value);
|
||||
// Preserve old value.
|
||||
// We don't have to validate as we can assume the local
|
||||
// was already valid for its type.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue