Skip to content

Commit 65a6bf1

Browse files
authored
fix handling of comptime-only union fields in Type.getUnionLayout (#25182)
Fixes #25180
1 parent 220c679 commit 65a6bf1

File tree

2 files changed

+29
-9
lines changed

2 files changed

+29
-9
lines changed

src/Type.zig

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3914,15 +3914,17 @@ pub fn getUnionLayout(loaded_union: InternPool.LoadedUnionType, zcu: *const Zcu)
39143914
explicit_align
39153915
else
39163916
field_ty.abiAlignment(zcu);
3917-
const field_size = field_ty.abiSize(zcu);
3918-
if (field_size > payload_size) {
3919-
payload_size = field_size;
3920-
biggest_field = @intCast(field_index);
3921-
}
3922-
if (field_size > 0 and field_align.compare(.gte, most_aligned_field_align)) {
3923-
most_aligned_field = @intCast(field_index);
3924-
most_aligned_field_align = field_align;
3925-
most_aligned_field_size = field_size;
3917+
if (field_ty.hasRuntimeBits(zcu)) {
3918+
const field_size = field_ty.abiSize(zcu);
3919+
if (field_size > payload_size) {
3920+
payload_size = field_size;
3921+
biggest_field = @intCast(field_index);
3922+
}
3923+
if (field_size > 0 and field_align.compare(.gte, most_aligned_field_align)) {
3924+
most_aligned_field = @intCast(field_index);
3925+
most_aligned_field_align = field_align;
3926+
most_aligned_field_size = field_size;
3927+
}
39263928
}
39273929
payload_align = payload_align.max(field_align);
39283930
}

test/behavior/union.zig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2325,3 +2325,21 @@ test "initialize empty field of union inside comptime-known struct constant" {
23252325
const val: Wrapper = .{ .inner = .{ .none = {} } };
23262326
comptime assert(val.inner.none == {});
23272327
}
2328+
2329+
test "union with function body field" {
2330+
const U = union {
2331+
f: fn () void,
2332+
fn foo() void {}
2333+
fn bar() void {}
2334+
};
2335+
const x: U = .{ .f = U.foo };
2336+
try std.testing.expect(x.f == U.foo);
2337+
x.f();
2338+
2339+
comptime var y: U = .{ .f = U.bar };
2340+
try std.testing.expect(y.f == U.bar);
2341+
y.f();
2342+
y.f = U.foo;
2343+
try std.testing.expect(y.f == U.foo);
2344+
y.f();
2345+
}

0 commit comments

Comments
 (0)