Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

interpret/visitor: support visiting with a PlaceTy #99259

Merged
merged 2 commits into from
Jul 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ fn valtree_into_mplace<'tcx>(

let offset = place_adjusted.layout.fields.offset(i);
place
.offset(
.offset_with_meta(
offset,
MemPlaceMeta::Meta(Scalar::from_machine_usize(
num_elems as u64,
Expand Down
14 changes: 12 additions & 2 deletions compiler/rustc_const_eval/src/interpret/operand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,15 +297,15 @@ impl<'tcx, Tag: Provenance> OpTy<'tcx, Tag> {
}
}

pub fn offset(
pub fn offset_with_meta(
&self,
offset: Size,
meta: MemPlaceMeta<Tag>,
layout: TyAndLayout<'tcx>,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx, Self> {
match self.try_as_mplace() {
Ok(mplace) => Ok(mplace.offset(offset, meta, layout, cx)?.into()),
Ok(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()),
Err(imm) => {
assert!(
matches!(*imm, Immediate::Uninit),
Expand All @@ -317,6 +317,16 @@ impl<'tcx, Tag: Provenance> OpTy<'tcx, Tag> {
}
}
}

pub fn offset(
&self,
offset: Size,
layout: TyAndLayout<'tcx>,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx, Self> {
assert!(!layout.is_unsized());
self.offset_with_meta(offset, MemPlaceMeta::None, layout, cx)
}
}

impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Expand Down
16 changes: 13 additions & 3 deletions compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl<Tag: Provenance> MemPlace<Tag> {
}

#[inline]
pub fn offset<'tcx>(
pub fn offset_with_meta<'tcx>(
self,
offset: Size,
meta: MemPlaceMeta<Tag>,
Expand Down Expand Up @@ -205,20 +205,30 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
}

#[inline]
pub fn offset(
pub fn offset_with_meta(
&self,
offset: Size,
meta: MemPlaceMeta<Tag>,
layout: TyAndLayout<'tcx>,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx, Self> {
Ok(MPlaceTy {
mplace: self.mplace.offset(offset, meta, cx)?,
mplace: self.mplace.offset_with_meta(offset, meta, cx)?,
align: self.align.restrict_for_offset(offset),
layout,
})
}

pub fn offset(
&self,
offset: Size,
layout: TyAndLayout<'tcx>,
cx: &impl HasDataLayout,
) -> InterpResult<'tcx, Self> {
assert!(!layout.is_unsized());
self.offset_with_meta(offset, MemPlaceMeta::None, layout, cx)
}

#[inline]
pub fn from_aligned_ptr(ptr: Pointer<Option<Tag>>, layout: TyAndLayout<'tcx>) -> Self {
MPlaceTy { mplace: MemPlace::from_ptr(ptr), layout, align: layout.align.abi }
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_const_eval/src/interpret/projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ where

// We do not look at `base.layout.align` nor `field_layout.align`, unlike
// codegen -- mostly to see if we can get away with that
base.offset(offset, meta, field_layout, self)
base.offset_with_meta(offset, meta, field_layout, self)
}

/// Gets the place of a field inside the place, and also the field's type.
Expand Down Expand Up @@ -193,9 +193,7 @@ where
let offset = stride * index; // `Size` multiplication
// All fields have the same layout.
let field_layout = base.layout.field(self, 0);
assert!(!field_layout.is_unsized());

base.offset(offset, MemPlaceMeta::None, field_layout, self)
base.offset(offset, field_layout, self)
}
_ => span_bug!(
self.cur_span(),
Expand All @@ -215,10 +213,10 @@ where
let abi::FieldsShape::Array { stride, .. } = base.layout.fields else {
span_bug!(self.cur_span(), "operand_array_fields: expected an array layout");
};
let layout = base.layout.field(self, 0);
let field_layout = base.layout.field(self, 0);
let dl = &self.tcx.data_layout;
// `Size` multiplication
Ok((0..len).map(move |i| base.offset(stride * i, MemPlaceMeta::None, layout, dl)))
Ok((0..len).map(move |i| base.offset(stride * i, field_layout, dl)))
}

/// Index into an array.
Expand Down Expand Up @@ -326,7 +324,7 @@ where
}
};
let layout = self.layout_of(ty)?;
base.offset(from_offset, meta, layout, self)
base.offset_with_meta(from_offset, meta, layout, self)
}

pub fn place_subslice(
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
self.visit_scalar(scalar, scalar_layout)?;
}
Abi::ScalarPair(a_layout, b_layout) => {
// We would validate these things as we descend into the fields,
// There is no `rustc_layout_scalar_valid_range_start` for pairs, so
// we would validate these things as we descend into the fields,
// but that can miss bugs in layout computation. Layout computation
// is subtle due to enums having ScalarPair layout, where one field
// is the discriminant.
Expand All @@ -867,7 +868,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
}
Abi::Vector { .. } => {
// No checks here, we assume layout computation gets this right.
// (This is harder to check since Miri does not represent these as `Immediate`.)
// (This is harder to check since Miri does not represent these as `Immediate`. We
// also cannot use field projections since this might be a newtype around a vector.)
}
Abi::Aggregate { .. } => {
// Nothing to do.
Expand Down
Loading