authorgravatar for 14016168+silversquirl@users.noreply.github.comSilver <14016168+silversquirl@users.noreply.github.com> 2025-09-18 05:39:47+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-09-18 12:47:17+02:00
loge14540399c1be3c052467a576bd317ea12194cdd
tree3a4850c968e9d211eae6a32aa02c93f03990f96e
parent87ca304a02807c6534ea6a9ba968c539d51718a9
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

fix handling of comptime-only union fields in `Type.getUnionLayout` (#25182)

Fixes #25180

2 files changed, 29 insertions(+), 9 deletions(-)

src/Type.zig+11-9
...@@ -3914,15 +3914,17 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)...@@ -3914,15 +3914,17 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
3914 explicit_align3914 explicit_align
3915 else3915 else
3916 field_ty.abiAlignment(zcu);3916 field_ty.abiAlignment(zcu);
3917 const field_size = field_ty.abiSize(zcu);3917 if (field_ty.hasRuntimeBits(zcu)) {
3918 if (field_size > payload_size) {3918 const field_size = field_ty.abiSize(zcu);
3919 payload_size = field_size;3919 if (field_size > payload_size) {
3920 biggest_field = @intCast(field_index);3920 payload_size = field_size;
3921 }3921 biggest_field = @intCast(field_index);
3922 if (field_size > 0 and field_align.compare(.gte, most_aligned_field_align)) {3922 }
3923 most_aligned_field = @intCast(field_index);3923 if (field_size > 0 and field_align.compare(.gte, most_aligned_field_align)) {
3924 most_aligned_field_align = field_align;3924 most_aligned_field = @intCast(field_index);
3925 most_aligned_field_size = field_size;3925 most_aligned_field_align = field_align;
3926 most_aligned_field_size = field_size;
3927 }
3926 }3928 }
3927 payload_align = payload_align.max(field_align);3929 payload_align = payload_align.max(field_align);
3928 }3930 }
test/behavior/union.zig+18
...@@ -2321,3 +2321,21 @@ test "initialize empty field of union inside comptime-known struct constant" {...@@ -2321,3 +2321,21 @@ test "initialize empty field of union inside comptime-known struct constant" {
2321 const val: Wrapper = .{ .inner = .{ .none = {} } };2321 const val: Wrapper = .{ .inner = .{ .none = {} } };
2322 comptime assert(val.inner.none == {});2322 comptime assert(val.inner.none == {});
2323}2323}
2324
2325test "union with function body field" {
2326 const U = union {
2327 f: fn () void,
2328 fn foo() void {}
2329 fn bar() void {}
2330 };
2331 const x: U = .{ .f = U.foo };
2332 try std.testing.expect(x.f == U.foo);
2333 x.f();
2334
2335 comptime var y: U = .{ .f = U.bar };
2336 try std.testing.expect(y.f == U.bar);
2337 y.f();
2338 y.f = U.foo;
2339 try std.testing.expect(y.f == U.foo);
2340 y.f();
2341}