Skip to content

Commit fa298be

Browse files
authored
Rollup merge of #99259 - RalfJung:visit-a-place, r=oli-obk
interpret/visitor: support visiting with a PlaceTy Finally we can visit a `PlaceTy` in a way that will only do `force_allocation` when needed ti visit a field. :) r? `@oli-obk`
2 parents 984ef42 + c4cb043 commit fa298be

File tree

6 files changed

+272
-50
lines changed

6 files changed

+272
-50
lines changed

Diff for: compiler/rustc_const_eval/src/const_eval/valtrees.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ fn valtree_into_mplace<'tcx>(
436436

437437
let offset = place_adjusted.layout.fields.offset(i);
438438
place
439-
.offset(
439+
.offset_with_meta(
440440
offset,
441441
MemPlaceMeta::Meta(Scalar::from_machine_usize(
442442
num_elems as u64,

Diff for: compiler/rustc_const_eval/src/interpret/operand.rs

+12-2
Original file line numberDiff line numberDiff line change
@@ -297,15 +297,15 @@ impl<'tcx, Tag: Provenance> OpTy<'tcx, Tag> {
297297
}
298298
}
299299

300-
pub fn offset(
300+
pub fn offset_with_meta(
301301
&self,
302302
offset: Size,
303303
meta: MemPlaceMeta<Tag>,
304304
layout: TyAndLayout<'tcx>,
305305
cx: &impl HasDataLayout,
306306
) -> InterpResult<'tcx, Self> {
307307
match self.try_as_mplace() {
308-
Ok(mplace) => Ok(mplace.offset(offset, meta, layout, cx)?.into()),
308+
Ok(mplace) => Ok(mplace.offset_with_meta(offset, meta, layout, cx)?.into()),
309309
Err(imm) => {
310310
assert!(
311311
matches!(*imm, Immediate::Uninit),
@@ -317,6 +317,16 @@ impl<'tcx, Tag: Provenance> OpTy<'tcx, Tag> {
317317
}
318318
}
319319
}
320+
321+
pub fn offset(
322+
&self,
323+
offset: Size,
324+
layout: TyAndLayout<'tcx>,
325+
cx: &impl HasDataLayout,
326+
) -> InterpResult<'tcx, Self> {
327+
assert!(!layout.is_unsized());
328+
self.offset_with_meta(offset, MemPlaceMeta::None, layout, cx)
329+
}
320330
}
321331

322332
impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

Diff for: compiler/rustc_const_eval/src/interpret/place.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<Tag: Provenance> MemPlace<Tag> {
163163
}
164164

165165
#[inline]
166-
pub fn offset<'tcx>(
166+
pub fn offset_with_meta<'tcx>(
167167
self,
168168
offset: Size,
169169
meta: MemPlaceMeta<Tag>,
@@ -199,20 +199,30 @@ impl<'tcx, Tag: Provenance> MPlaceTy<'tcx, Tag> {
199199
}
200200

201201
#[inline]
202-
pub fn offset(
202+
pub fn offset_with_meta(
203203
&self,
204204
offset: Size,
205205
meta: MemPlaceMeta<Tag>,
206206
layout: TyAndLayout<'tcx>,
207207
cx: &impl HasDataLayout,
208208
) -> InterpResult<'tcx, Self> {
209209
Ok(MPlaceTy {
210-
mplace: self.mplace.offset(offset, meta, cx)?,
210+
mplace: self.mplace.offset_with_meta(offset, meta, cx)?,
211211
align: self.align.restrict_for_offset(offset),
212212
layout,
213213
})
214214
}
215215

216+
pub fn offset(
217+
&self,
218+
offset: Size,
219+
layout: TyAndLayout<'tcx>,
220+
cx: &impl HasDataLayout,
221+
) -> InterpResult<'tcx, Self> {
222+
assert!(!layout.is_unsized());
223+
self.offset_with_meta(offset, MemPlaceMeta::None, layout, cx)
224+
}
225+
216226
#[inline]
217227
pub fn from_aligned_ptr(ptr: Pointer<Option<Tag>>, layout: TyAndLayout<'tcx>) -> Self {
218228
MPlaceTy { mplace: MemPlace::from_ptr(ptr), layout, align: layout.align.abi }

Diff for: compiler/rustc_const_eval/src/interpret/projection.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ where
6363

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

6969
/// Gets the place of a field inside the place, and also the field's type.
@@ -193,9 +193,7 @@ where
193193
let offset = stride * index; // `Size` multiplication
194194
// All fields have the same layout.
195195
let field_layout = base.layout.field(self, 0);
196-
assert!(!field_layout.is_unsized());
197-
198-
base.offset(offset, MemPlaceMeta::None, field_layout, self)
196+
base.offset(offset, field_layout, self)
199197
}
200198
_ => span_bug!(
201199
self.cur_span(),
@@ -215,10 +213,10 @@ where
215213
let abi::FieldsShape::Array { stride, .. } = base.layout.fields else {
216214
span_bug!(self.cur_span(), "operand_array_fields: expected an array layout");
217215
};
218-
let layout = base.layout.field(self, 0);
216+
let field_layout = base.layout.field(self, 0);
219217
let dl = &self.tcx.data_layout;
220218
// `Size` multiplication
221-
Ok((0..len).map(move |i| base.offset(stride * i, MemPlaceMeta::None, layout, dl)))
219+
Ok((0..len).map(move |i| base.offset(stride * i, field_layout, dl)))
222220
}
223221

224222
/// Index into an array.
@@ -326,7 +324,7 @@ where
326324
}
327325
};
328326
let layout = self.layout_of(ty)?;
329-
base.offset(from_offset, meta, layout, self)
327+
base.offset_with_meta(from_offset, meta, layout, self)
330328
}
331329

332330
pub fn place_subslice(

Diff for: compiler/rustc_const_eval/src/interpret/validity.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
853853
self.visit_scalar(scalar, scalar_layout)?;
854854
}
855855
Abi::ScalarPair(a_layout, b_layout) => {
856-
// We would validate these things as we descend into the fields,
856+
// There is no `rustc_layout_scalar_valid_range_start` for pairs, so
857+
// we would validate these things as we descend into the fields,
857858
// but that can miss bugs in layout computation. Layout computation
858859
// is subtle due to enums having ScalarPair layout, where one field
859860
// is the discriminant.
@@ -867,7 +868,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
867868
}
868869
Abi::Vector { .. } => {
869870
// No checks here, we assume layout computation gets this right.
870-
// (This is harder to check since Miri does not represent these as `Immediate`.)
871+
// (This is harder to check since Miri does not represent these as `Immediate`. We
872+
// also cannot use field projections since this might be a newtype around a vector.)
871873
}
872874
Abi::Aggregate { .. } => {
873875
// Nothing to do.

0 commit comments

Comments
 (0)