diff --git a/src/value.zig b/src/value.zig index 306e31c0a7..98842a4ca7 100644 --- a/src/value.zig +++ b/src/value.zig @@ -1340,6 +1340,14 @@ pub const Value = extern union { const int = mod.global_error_set.get(val.castTag(.@"error").?.data.name).?; std.mem.writeInt(Int, buffer[0..@sizeOf(Int)], @intCast(Int, int), endian); }, + .Union => switch (ty.containerLayout()) { + .Auto => unreachable, + .Extern => @panic("TODO implement writeToMemory for extern unions"), + .Packed => { + const byte_count = (@intCast(usize, ty.bitSize(target)) + 7) / 8; + writeToPackedMemory(val, ty, mod, buffer[0..byte_count], 0); + }, + }, else => @panic("TODO implement writeToMemory for more types"), } } @@ -1430,6 +1438,17 @@ pub const Value = extern union { } }, }, + .Union => switch (ty.containerLayout()) { + .Auto => unreachable, // Sema is supposed to have emitted a compile error already + .Extern => unreachable, // Handled in non-packed writeToMemory + .Packed => { + const field_index = ty.unionTagFieldIndex(val.unionTag(), mod); + const field_type = ty.unionFields().values()[field_index.?].ty; + const field_val = val.fieldValue(field_type, field_index.?); + + field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset); + }, + }, else => @panic("TODO implement writeToPackedMemory for more types"), } } diff --git a/test/behavior/comptime_memory.zig b/test/behavior/comptime_memory.zig index e08dad68f0..a4f9f2f7a9 100644 --- a/test/behavior/comptime_memory.zig +++ b/test/behavior/comptime_memory.zig @@ -394,3 +394,21 @@ test "accessing reinterpreted memory of parent object" { try testing.expect(b == expected); } } + +test "bitcast packed union to integer" { + const U = packed union { + x: u1, + y: u2, + }; + + comptime { + const a = U{ .x = 1 }; + const b = U{ .y = 2 }; + const cast_a = @bitCast(u2, a); + const cast_b = @bitCast(u2, b); + + // truncated because the upper bit is garbage memory that we don't care about + try testing.expectEqual(@as(u1, 1), @truncate(u1, cast_a)); + try testing.expectEqual(@as(u2, 2), cast_b); + } +}