stage2: explicitly tagged enums no longer have one possible value

Previously, Zig had inconsistent semantics for an enum like this:

`enum(u8){zero = 0}`

Although in theory this can only hold one possible value, the tag
`zero`, Zig no longer will treat the type this way. It will do loads and
stores, as if the type has runtime bits.

Closes #12619

Tests passed locally:
 * test-behavior
 * test-cases
This commit is contained in:
Andrew Kelley
2022-08-24 20:27:11 -07:00
parent af19909b9c
commit 7453f56e67
10 changed files with 113 additions and 60 deletions

View File

@@ -1368,18 +1368,20 @@ pub const Union = struct {
}
}
payload_align = @maximum(payload_align, 1);
if (!have_tag or fields.len <= 1) return .{
.abi_size = std.mem.alignForwardGeneric(u64, payload_size, payload_align),
.abi_align = payload_align,
.most_aligned_field = most_aligned_field,
.most_aligned_field_size = most_aligned_field_size,
.biggest_field = biggest_field,
.payload_size = payload_size,
.payload_align = payload_align,
.tag_align = 0,
.tag_size = 0,
.padding = 0,
};
if (!have_tag or !u.tag_ty.hasRuntimeBits()) {
return .{
.abi_size = std.mem.alignForwardGeneric(u64, payload_size, payload_align),
.abi_align = payload_align,
.most_aligned_field = most_aligned_field,
.most_aligned_field_size = most_aligned_field_size,
.biggest_field = biggest_field,
.payload_size = payload_size,
.payload_align = payload_align,
.tag_align = 0,
.tag_size = 0,
.padding = 0,
};
}
// Put the tag before or after the payload depending on which one's
// alignment is greater.
const tag_size = u.tag_ty.abiSize(target);