about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBen Kimock <kimockb@gmail.com>2022-08-28 13:07:33 -0400
committerBen Kimock <kimockb@gmail.com>2022-08-29 00:31:46 -0400
commit70b960b879528b6ef5f8df4e0f8e2d8b72e1d221 (patch)
treeb65b45f27e63f0cce3423b0b9b9877b567c05752
parent88665133b709928a88efed760d1219f2d821aea2 (diff)
downloadrust-70b960b879528b6ef5f8df4e0f8e2d8b72e1d221.tar.gz
rust-70b960b879528b6ef5f8df4e0f8e2d8b72e1d221.zip
Skip field retagging on ZSTs, it can take forever
-rw-r--r--src/stacked_borrows/mod.rs8
-rw-r--r--tests/pass/stacked-borrows/zst-field-retagging-terminates.rs5
2 files changed, 13 insertions, 0 deletions
diff --git a/src/stacked_borrows/mod.rs b/src/stacked_borrows/mod.rs
index 66fdd685def..5cdcaecc17d 100644
--- a/src/stacked_borrows/mod.rs
+++ b/src/stacked_borrows/mod.rs
@@ -973,6 +973,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
             }
 
             fn visit_value(&mut self, place: &PlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> {
+                // If this place is smaller than a pointer, we know that it can't contain any
+                // pointers we need to retag, so we can stop recursion early.
+                // This optimization is crucial for ZSTs, because they can contain way more fields
+                // than we can ever visit.
+                if !place.layout.is_unsized() && place.layout.size < self.ecx.pointer_size() {
+                    return Ok(());
+                }
+
                 if let Some((ref_kind, protector)) = qualify(place.layout.ty, self.kind) {
                     self.retag_place(place, ref_kind, self.retag_cause, protector)?;
                 } else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {
diff --git a/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs b/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
new file mode 100644
index 00000000000..2099c5ad149
--- /dev/null
+++ b/tests/pass/stacked-borrows/zst-field-retagging-terminates.rs
@@ -0,0 +1,5 @@
+//@compile-flags: -Zmiri-retag-fields
+fn main() {
+    let array = [(); usize::MAX];
+    drop(array); // Pass the array to a function, retagging its fields
+}