Skip to content

Commit 284b59c

Browse files
committed
Auto merge of #2517 - saethlin:zst-field-retagging, r=RalfJung
Skip field retagging on ZSTs, it can take forever I just tried running the `alloc`'s tests with `miri-test-libstd` with field retagging enabled. The test suite eventually hangs on a few tests which pass around ZSTs that have a lot of fields. I don't really know how to test this effectively. The test passes, but if you remove this fast-path it effectively just hangs the interpreter. And since it hangs _inside_ a step, there's no hope for doing some kind of timeout within the test.
2 parents fec1c7a + c9b36b4 commit 284b59c

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

src/stacked_borrows/mod.rs

+8
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
973973
}
974974

975975
fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
976+
// If this place is smaller than a pointer, we know that it can't contain any
977+
// pointers we need to retag, so we can stop recursion early.
978+
// This optimization is crucial for ZSTs, because they can contain way more fields
979+
// than we can ever visit.
980+
if !place.layout.is_unsized() && place.layout.size < self.ecx.pointer_size() {
981+
return Ok(());
982+
}
983+
976984
if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) {
977985
self.retag_place(place, ref_kind, self.retag_cause, protector)?;
978986
} else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//@compile-flags: -Zmiri-retag-fields
2+
// Checks that the test does not run forever (which relies on a fast path).
3+
fn main() {
4+
let array = [(); usize::MAX];
5+
drop(array); // Pass the array to a function, retagging its fields
6+
}

0 commit comments

Comments
 (0)