Commit 65a6bf1267
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);
}
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();
+}