diff --git a/src/Type.zig b/src/Type.zig index f8f13ada44..3ef95b285c 100644 --- 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 index 04d07f91ae..f821097c27 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -2321,3 +2321,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(); +}