Skip to content

Commit d34d7f1

Browse files
committed
compiler/hir/check: retain layout info through transparent type check
Postpone the alignment calculation and retain the entire layout information when checking transparent types for violations. This allows for future diagnostic improvements because we now know the exact type layouts of violating fields, or know exactly why their layout was not available.
1 parent b14b074 commit d34d7f1

File tree

1 file changed

+6
-6
lines changed
  • compiler/rustc_hir_analysis/src/check

1 file changed

+6
-6
lines changed

compiler/rustc_hir_analysis/src/check/check.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
11301130
return;
11311131
}
11321132

1133-
// For each field, figure out if it's known to be a ZST and align(1), with "known"
1133+
// For each field, figure out if it's known to be a ZST with layout, with "known"
11341134
// respecting #[non_exhaustive] attributes.
11351135
let field_infos = adt.all_fields().map(|field| {
11361136
let ty = field.ty(tcx, GenericArgs::identity_for_item(tcx, field.did));
@@ -1139,9 +1139,8 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
11391139
// We are currently checking the type this field came from, so it must be local
11401140
let span = tcx.hir().span_if_local(field.did).unwrap();
11411141
let zst = layout.is_ok_and(|layout| layout.is_zst());
1142-
let align = layout.ok().map(|layout| layout.align.abi.bytes());
11431142
if !zst {
1144-
return (span, zst, align, None);
1143+
return (span, zst, layout, None);
11451144
}
11461145

11471146
fn check_non_exhaustive<'tcx>(
@@ -1176,20 +1175,21 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
11761175
}
11771176
}
11781177

1179-
(span, zst, align, check_non_exhaustive(tcx, ty).break_value())
1178+
(span, zst, layout, check_non_exhaustive(tcx, ty).break_value())
11801179
});
11811180

11821181
let non_zst_fields = field_infos
11831182
.clone()
1184-
.filter_map(|(span, zst, _align, _non_exhaustive)| if !zst { Some(span) } else { None });
1183+
.filter_map(|(span, zst, _layout, _non_exhaustive)| if !zst { Some(span) } else { None });
11851184
let non_zst_count = non_zst_fields.clone().count();
11861185
if non_zst_count >= 2 {
11871186
bad_non_zero_sized_fields(tcx, adt, non_zst_count, non_zst_fields, tcx.def_span(adt.did()));
11881187
}
11891188
let incompatible_zst_fields =
11901189
field_infos.clone().filter(|(_, _, _, opt)| opt.is_some()).count();
11911190
let incompat = incompatible_zst_fields + non_zst_count >= 2 && non_zst_count < 2;
1192-
for (span, zst, align, non_exhaustive) in field_infos {
1191+
for (span, zst, layout, non_exhaustive) in field_infos {
1192+
let align = layout.ok().map(|layout| layout.align.abi.bytes());
11931193
if zst && align != Some(1) {
11941194
let mut err = struct_span_err!(
11951195
tcx.sess,

0 commit comments

Comments
 (0)