Skip to content

Commit 012f9a3

Browse files
committed
Review feedback
1 parent c63a204 commit 012f9a3

File tree

2 files changed

+23
-14
lines changed

2 files changed

+23
-14
lines changed

compiler/rustc_abi/src/layout.rs

+22-13
Original file line numberDiff line numberDiff line change
@@ -729,34 +729,43 @@ pub trait LayoutCalculator {
729729
align = align.max(AbiAndPrefAlign::new(repr_align));
730730
}
731731

732-
let mut optimize = !repr.inhibit_union_abi_opt();
732+
// If all the non-ZST fields have the same ABI and union ABI optimizations aren't
733+
// disabled, we can use that common ABI for the union as a whole.
734+
struct AbiMismatch;
735+
let mut common_non_zst_abi_and_align = if repr.inhibit_union_abi_opt() {
736+
// Can't optimize
737+
Err(AbiMismatch)
738+
} else {
739+
Ok(None)
740+
};
741+
733742
let mut size = Size::ZERO;
734-
let mut common_non_zst_abi_and_align: Option<(Abi, AbiAndPrefAlign)> = None;
735743
let only_variant = &variants[FIRST_VARIANT];
736744
for field in only_variant {
737745
assert!(field.0.is_sized());
738746

739-
if !field.0.is_zst() && optimize {
747+
if !field.0.is_zst() && !common_non_zst_abi_and_align.is_err() {
740748
// Discard valid range information and allow undef
741749
let field_abi = field.abi().to_union();
742750

743-
if let Some((abi, align)) = &mut common_non_zst_abi_and_align {
744-
if *abi != field_abi {
751+
if let Ok(Some((common_abi, common_align))) = &mut common_non_zst_abi_and_align {
752+
if *common_abi != field_abi {
745753
// Different fields have different ABI: disable opt
746-
optimize = false;
754+
common_non_zst_abi_and_align = Err(AbiMismatch);
747755
} else {
748756
// Fields with the same non-Aggregate ABI should also
749757
// have the same alignment
750-
if !matches!(abi, Abi::Aggregate { .. }) {
758+
if !matches!(common_abi, Abi::Aggregate { .. }) {
751759
assert_eq!(
752-
align.abi,
760+
*common_align,
753761
field.align().abi,
754762
"non-Aggregate field with matching ABI but differing alignment"
755763
);
756764
}
757765
}
758766
} else {
759-
common_non_zst_abi_and_align = Some((field_abi, field.align()));
767+
// First non-ZST field: record its ABI and alignment
768+
common_non_zst_abi_and_align = Ok(Some((field_abi, field.align().abi)));
760769
}
761770
}
762771

@@ -770,11 +779,11 @@ pub trait LayoutCalculator {
770779

771780
// If all non-ZST fields have the same ABI, we may forward that ABI
772781
// for the union as a whole, unless otherwise inhibited.
773-
let abi = match (optimize, common_non_zst_abi_and_align) {
774-
(false, _) | (_, None) => Abi::Aggregate { sized: true },
775-
(true, Some((abi, _))) => {
782+
let abi = match common_non_zst_abi_and_align {
783+
Err(AbiMismatch) | Ok(None) => Abi::Aggregate { sized: true },
784+
Ok(Some((abi, _))) => {
776785
if abi.inherent_align(dl).map(|a| a.abi) != Some(align.abi) {
777-
// Mismatched alignment: disable opt
786+
// Mismatched alignment (e.g. union is #[repr(packed)]): disable opt
778787
Abi::Aggregate { sized: true }
779788
} else {
780789
abi

compiler/rustc_abi/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,7 @@ impl Abi {
13061306
})
13071307
}
13081308

1309-
/// Discard valid range information and allow undef
1309+
/// Discard validity range information and allow undef.
13101310
pub fn to_union(&self) -> Self {
13111311
assert!(self.is_sized());
13121312
match *self {

0 commit comments

Comments
 (0)