aboutsummaryrefslogtreecommitdiff
path: root/src/value.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-08-21 14:27:34 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-08-22 13:54:14 -0700
commitada0010471163a3accca8976185fbb6bb59c914f (patch)
treed5035071ea3cb73677e381c0052e137fded064ac /src/value.zig
parent6a5463951f0aa11cbdd5575cc78e85cd2ed10b46 (diff)
downloadzig-ada0010471163a3accca8976185fbb6bb59c914f.tar.gz
zig-ada0010471163a3accca8976185fbb6bb59c914f.zip
compiler: move unions into InternPool
There are a couple concepts here worth understanding: Key.UnionType - This type is available *before* resolving the union's fields. The enum tag type, number of fields, and field names, field types, and field alignments are not available with this. InternPool.UnionType - This one can be obtained from the above type with `InternPool.loadUnionType` which asserts that the union's enum tag type has been resolved. This one has all the information available. Additionally: * ZIR: Turn an unused bit into `any_aligned_fields` flag to help semantic analysis know whether a union has explicit alignment on any fields (usually not). * Sema: delete `resolveTypeRequiresComptime` which had the same type signature and near-duplicate logic to `typeRequiresComptime`. - Make opaque types not report comptime-only (this was inconsistent between the two implementations of this function). * Implement accepted proposal #12556 which is a breaking change.
Diffstat (limited to 'src/value.zig')
-rw-r--r--src/value.zig28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/value.zig b/src/value.zig
index fdf061c680..7612a9f8c2 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -734,6 +734,7 @@ pub const Value = struct {
buffer: []u8,
bit_offset: usize,
) error{ ReinterpretDeclRef, OutOfMemory }!void {
+ const ip = &mod.intern_pool;
const target = mod.getTarget();
const endian = target.cpu.arch.endian();
if (val.isUndef(mod)) {
@@ -759,7 +760,7 @@ pub const Value = struct {
const bits = ty.intInfo(mod).bits;
if (bits == 0) return;
- switch (mod.intern_pool.indexToKey((try val.intFromEnum(ty, mod)).toIntern()).int.storage) {
+ switch (ip.indexToKey((try val.intFromEnum(ty, mod)).toIntern()).int.storage) {
inline .u64, .i64 => |int| std.mem.writeVarPackedInt(buffer, bit_offset, bits, int, endian),
.big_int => |bigint| bigint.writePackedTwosComplement(buffer, bit_offset, bits, endian),
else => unreachable,
@@ -794,7 +795,7 @@ pub const Value = struct {
.Packed => {
var bits: u16 = 0;
const fields = ty.structFields(mod).values();
- const storage = mod.intern_pool.indexToKey(val.toIntern()).aggregate.storage;
+ const storage = ip.indexToKey(val.toIntern()).aggregate.storage;
for (fields, 0..) |field, i| {
const field_bits = @as(u16, @intCast(field.ty.bitSize(mod)));
const field_val = switch (storage) {
@@ -807,16 +808,19 @@ pub const Value = struct {
}
},
},
- .Union => switch (ty.containerLayout(mod)) {
- .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), mod);
- const field_type = ty.unionFields(mod).values()[field_index.?].ty;
- const field_val = try val.fieldValue(mod, field_index.?);
-
- return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);
- },
+ .Union => {
+ const union_obj = mod.typeToUnion(ty).?;
+ switch (union_obj.getLayout(ip)) {
+ .Auto => unreachable, // Sema is supposed to have emitted a compile error already
+ .Extern => unreachable, // Handled in non-packed writeToMemory
+ .Packed => {
+ const field_index = mod.unionTagFieldIndex(union_obj, val.unionTag(mod)).?;
+ const field_type = union_obj.field_types.get(ip)[field_index].toType();
+ const field_val = try val.fieldValue(mod, field_index);
+
+ return field_val.writeToPackedMemory(field_type, mod, buffer, bit_offset);
+ },
+ }
},
.Pointer => {
assert(!ty.isSlice(mod)); // No well defined layout.