about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/util/alignment.rs
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2022-08-02 12:21:38 -0400
committerRalf Jung <post@ralfj.de>2022-08-03 09:59:08 -0400
commit9097ce905427c30bd262f62a403f1e987ebb10c6 (patch)
treee0e6142fa1ea948731a41f0f86150e33d3068b5a /compiler/rustc_const_eval/src/util/alignment.rs
parentbd84c73ffe0a54ce2d77c92948a26ffa8fec04a3 (diff)
downloadrust-9097ce905427c30bd262f62a403f1e987ebb10c6.tar.gz
rust-9097ce905427c30bd262f62a403f1e987ebb10c6.zip
fix is_disaligned logic for nested packed structs
Diffstat (limited to 'compiler/rustc_const_eval/src/util/alignment.rs')
-rw-r--r--compiler/rustc_const_eval/src/util/alignment.rs28
1 files changed, 12 insertions, 16 deletions
diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs
index fe4a726fe12..4f39dad205a 100644
--- a/compiler/rustc_const_eval/src/util/alignment.rs
+++ b/compiler/rustc_const_eval/src/util/alignment.rs
@@ -48,20 +48,16 @@ fn is_within_packed<'tcx, L>(
 where
     L: HasLocalDecls<'tcx>,
 {
-    for (place_base, elem) in place.iter_projections().rev() {
-        match elem {
-            // encountered a Deref, which is ABI-aligned
-            ProjectionElem::Deref => break,
-            ProjectionElem::Field(..) => {
-                let ty = place_base.ty(local_decls, tcx).ty;
-                match ty.kind() {
-                    ty::Adt(def, _) => return def.repr().pack,
-                    _ => {}
-                }
-            }
-            _ => {}
-        }
-    }
-
-    None
+    place
+        .iter_projections()
+        .rev()
+        // Stop at `Deref`; standard ABI alignment applies there.
+        .take_while(|(_base, elem)| !matches!(elem, ProjectionElem::Deref))
+        // Consider the packed alignments at play here...
+        .filter_map(|(base, _elem)| {
+            base.ty(local_decls, tcx).ty.ty_adt_def().and_then(|adt| adt.repr().pack)
+        })
+        // ... and compute their minimum.
+        // The overall smallest alignment is what matters.
+        .min()
 }