Skip to content

Commit ac4f6ab

Browse files
committed
forcing instead of normalization
Normalziation does not work well for dyamically sized types
1 parent 9b71a8f commit ac4f6ab

File tree

3 files changed

+17
-12
lines changed

3 files changed

+17
-12
lines changed

src/librustc_mir/interpret/operand.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
217217
/// Normalice `place.ptr` to a `Pointer` if this is a place and not a ZST.
218218
/// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
219219
#[inline]
220-
pub fn normalize_op_ptr(
220+
pub fn force_op_ptr(
221221
&self,
222222
op: OpTy<'tcx, M::PointerTag>,
223223
) -> InterpResult<'tcx, OpTy<'tcx, M::PointerTag>> {
224224
match op.try_as_mplace() {
225-
Ok(mplace) => Ok(self.normalize_mplace_ptr(mplace)?.into()),
226-
Err(imm) => Ok(imm.into()), // Nothing to normalize
225+
Ok(mplace) => Ok(self.force_mplace_ptr(mplace)?.into()),
226+
Err(imm) => Ok(imm.into()), // Nothing to cast/force
227227
}
228228
}
229229

src/librustc_mir/interpret/place.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -327,15 +327,13 @@ where
327327
self.memory.check_ptr_access(place.ptr, size, place.align)
328328
}
329329

330-
/// Normalice `place.ptr` to a `Pointer` if this is not a ZST.
330+
/// Force `place.ptr` to a `Pointer`.
331331
/// Can be helpful to avoid lots of `force_ptr` calls later, if this place is used a lot.
332-
pub fn normalize_mplace_ptr(
332+
pub fn force_mplace_ptr(
333333
&self,
334334
mut place: MPlaceTy<'tcx, M::PointerTag>,
335335
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
336-
if !place.layout.is_zst() {
337-
place.mplace.ptr = self.force_ptr(place.mplace.ptr)?.into();
338-
}
336+
place.mplace.ptr = self.force_ptr(place.mplace.ptr)?.into();
339337
Ok(place)
340338
}
341339

src/librustc_mir/interpret/validity.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,12 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
444444
// `!` is a ZST and we want to validate it.
445445
// Normalize before handing `place` to tracking because that will
446446
// check for duplicates.
447-
let place = self.ecx.normalize_mplace_ptr(place)?;
447+
let place = if size.bytes() > 0 {
448+
self.ecx.force_mplace_ptr(place)
449+
.expect("we already bounds-checked")
450+
} else {
451+
place
452+
};
448453
let path = &self.path;
449454
ref_tracking.track(place, || {
450455
// We need to clone the path anyway, make sure it gets created
@@ -578,8 +583,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
578583
let ty_size = self.ecx.layout_of(tys)?.size;
579584
// This is the size in bytes of the whole array.
580585
let size = ty_size * len;
581-
// Size is not 0, get a pointer (no cast because we normalized in validate_operand).
582-
let ptr = mplace.ptr.assert_ptr();
586+
// Size is not 0, get a pointer.
587+
let ptr = self.ecx.force_ptr(mplace.ptr)?;
583588

584589
// NOTE: Keep this in sync with the handling of integer and float
585590
// types above, in `visit_primitive`.
@@ -654,8 +659,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
654659
ecx: self,
655660
};
656661

662+
// Try to cast to ptr *once* instead of all the time.
663+
let op = self.force_op_ptr(op).unwrap_or(op);
664+
657665
// Run it
658-
let op = self.normalize_op_ptr(op)?; // avoid doing ptr-to-int all the time
659666
visitor.visit_value(op)
660667
}
661668
}

0 commit comments

Comments
 (0)