about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_const_eval/src')
-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()
 }