diff options
| author | bors <bors@rust-lang.org> | 2022-07-30 23:47:51 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-07-30 23:47:51 +0000 |
| commit | a2318651d4d2c6280a5047544cbf4180119ba966 (patch) | |
| tree | 43144d29701ef870ba8d3b0b5abe197aa73e463c /compiler | |
| parent | 0f4bcadb46006bc484dad85616b484f93879ca4e (diff) | |
| parent | 1e7e74557285c6307c5cf78c88b0a3356d8b7498 (diff) | |
| download | rust-a2318651d4d2c6280a5047544cbf4180119ba966.tar.gz rust-a2318651d4d2c6280a5047544cbf4180119ba966.zip | |
Auto merge of #99959 - cuviper:niche-size, r=eddyb
Fix the size of niche enums with ZST alignment For enums with an aligned ZST variant, like `[T; 0]`, the niche layout was not computing a sufficient size to be consistent with alignment. Now we pad that size up to the alignment, and also make sure to only use the niche variant's ABI when the size and alignment still match. Fixes #99836 r? `@eddyb`
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_middle/src/ty/layout.rs | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index dde55dd9655..833edd22805 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1231,11 +1231,15 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { .collect::<Result<IndexVec<VariantIdx, _>, _>>()?; let offset = st[i].fields().offset(field_index) + niche.offset; - let size = st[i].size(); + + // Align the total size to the largest alignment. + let size = st[i].size().align_to(align.abi); let abi = if st.iter().all(|v| v.abi().is_uninhabited()) { Abi::Uninhabited - } else { + } else if align == st[i].align() && size == st[i].size() { + // When the total alignment and size match, we can use the + // same ABI as the scalar variant with the reserved niche. match st[i].abi() { Abi::Scalar(_) => Abi::Scalar(niche_scalar), Abi::ScalarPair(first, second) => { @@ -1249,6 +1253,8 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { } _ => Abi::Aggregate { sized: true }, } + } else { + Abi::Aggregate { sized: true } }; let largest_niche = Niche::from_scalar(dl, offset, niche_scalar); |
