diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-08-21 14:27:34 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-08-22 13:54:14 -0700 |
| commit | ada0010471163a3accca8976185fbb6bb59c914f (patch) | |
| tree | d5035071ea3cb73677e381c0052e137fded064ac /src/value.zig | |
| parent | 6a5463951f0aa11cbdd5575cc78e85cd2ed10b46 (diff) | |
| download | zig-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.zig | 28 |
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. |
