zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 65a6bf1267770c4d27785cd1fbfa9fb1e5dc30c9 (tree)
parent 220c6795233bfdc9b93dfb3364b21705b1e6c903
Author: Silver <14016168+silversquirl@users.noreply.github.com>
Date:   Thu, 18 Sep 2025 05:39:47 +0100

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

Fixes #25180
Diffstat:
Msrc/Type.zig | 20+++++++++++---------
Mtest/behavior/union.zig | 18++++++++++++++++++
2 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/src/Type.zig b/src/Type.zig @@ -3914,15 +3914,17 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu) explicit_align else field_ty.abiAlignment(zcu); - const field_size = field_ty.abiSize(zcu); - if (field_size > payload_size) { - payload_size = field_size; - biggest_field = @intCast(field_index); - } - if (field_size > 0 and field_align.compare(.gte, most_aligned_field_align)) { - most_aligned_field = @intCast(field_index); - most_aligned_field_align = field_align; - most_aligned_field_size = field_size; + if (field_ty.hasRuntimeBits(zcu)) { + const field_size = field_ty.abiSize(zcu); + if (field_size > payload_size) { + payload_size = field_size; + biggest_field = @intCast(field_index); + } + if (field_size > 0 and field_align.compare(.gte, most_aligned_field_align)) { + most_aligned_field = @intCast(field_index); + most_aligned_field_align = field_align; + most_aligned_field_size = field_size; + } } payload_align = payload_align.max(field_align); } diff --git a/test/behavior/union.zig b/test/behavior/union.zig @@ -2325,3 +2325,21 @@ test "initialize empty field of union inside comptime-known struct constant" { const val: Wrapper = .{ .inner = .{ .none = {} } }; comptime assert(val.inner.none == {}); } + +test "union with function body field" { + const U = union { + f: fn () void, + fn foo() void {} + fn bar() void {} + }; + const x: U = .{ .f = U.foo }; + try std.testing.expect(x.f == U.foo); + x.f(); + + comptime var y: U = .{ .f = U.bar }; + try std.testing.expect(y.f == U.bar); + y.f(); + y.f = U.foo; + try std.testing.expect(y.f == U.foo); + y.f(); +}