summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_const_eval/src/util/alignment.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_const_eval/src/util/alignment.rs')
-rw-r--r--compiler/rustc_const_eval/src/util/alignment.rs10
1 files changed, 9 insertions, 1 deletions
diff --git a/compiler/rustc_const_eval/src/util/alignment.rs b/compiler/rustc_const_eval/src/util/alignment.rs
index 2e0643afb..8642dfccd 100644
--- a/compiler/rustc_const_eval/src/util/alignment.rs
+++ b/compiler/rustc_const_eval/src/util/alignment.rs
@@ -21,10 +21,18 @@ where
};
let ty = place.ty(local_decls, tcx).ty;
+ let unsized_tail = || tcx.struct_tail_with_normalize(ty, |ty| ty, || {});
match tcx.layout_of(param_env.and(ty)) {
- Ok(layout) if layout.align.abi <= pack => {
+ Ok(layout)
+ if layout.align.abi <= pack
+ && (layout.is_sized()
+ || matches!(unsized_tail().kind(), ty::Slice(..) | ty::Str)) =>
+ {
// If the packed alignment is greater or equal to the field alignment, the type won't be
// further disaligned.
+ // However we need to ensure the field is sized; for unsized fields, `layout.align` is
+ // just an approximation -- except when the unsized tail is a slice, where the alignment
+ // is fully determined by the type.
debug!(
"is_disaligned({:?}) - align = {}, packed = {}; not disaligned",
place,