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.
This commit is contained in:
Andrew Kelley
2023-08-21 14:27:34 -07:00
parent 6a5463951f
commit ada0010471
27 changed files with 1478 additions and 1440 deletions

View File

@@ -185,8 +185,9 @@ pub fn generateSymbol(
defer tracy.end();
const mod = bin_file.options.module.?;
const ip = &mod.intern_pool;
var typed_value = arg_tv;
switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
switch (ip.indexToKey(typed_value.val.toIntern())) {
.runtime_value => |rt| typed_value.val = rt.val.toValue(),
else => {},
}
@@ -205,7 +206,7 @@ pub fn generateSymbol(
return .ok;
}
switch (mod.intern_pool.indexToKey(typed_value.val.toIntern())) {
switch (ip.indexToKey(typed_value.val.toIntern())) {
.int_type,
.ptr_type,
.array_type,
@@ -385,7 +386,7 @@ pub fn generateSymbol(
try code.appendNTimes(0, padding);
}
},
.aggregate => |aggregate| switch (mod.intern_pool.indexToKey(typed_value.ty.toIntern())) {
.aggregate => |aggregate| switch (ip.indexToKey(typed_value.ty.toIntern())) {
.array_type => |array_type| switch (aggregate.storage) {
.bytes => |bytes| try code.appendSlice(bytes),
.elems, .repeated_elem => {
@@ -442,7 +443,7 @@ pub fn generateSymbol(
if (!field_ty.toType().hasRuntimeBits(mod)) continue;
const field_val = switch (aggregate.storage) {
.bytes => |bytes| try mod.intern_pool.get(mod.gpa, .{ .int = .{
.bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
.ty = field_ty,
.storage = .{ .u64 = bytes[index] },
} }),
@@ -484,7 +485,7 @@ pub fn generateSymbol(
const field_ty = field.ty;
const field_val = switch (aggregate.storage) {
.bytes => |bytes| try mod.intern_pool.get(mod.gpa, .{ .int = .{
.bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
.ty = field_ty.toIntern(),
.storage = .{ .u64 = bytes[index] },
} }),
@@ -522,8 +523,8 @@ pub fn generateSymbol(
if (!field_ty.hasRuntimeBits(mod)) continue;
const field_val = switch (mod.intern_pool.indexToKey(typed_value.val.toIntern()).aggregate.storage) {
.bytes => |bytes| try mod.intern_pool.get(mod.gpa, .{ .int = .{
const field_val = switch (ip.indexToKey(typed_value.val.toIntern()).aggregate.storage) {
.bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
.ty = field_ty.toIntern(),
.storage = .{ .u64 = bytes[field_offset.field] },
} }),
@@ -570,10 +571,9 @@ pub fn generateSymbol(
}
}
const union_ty = mod.typeToUnion(typed_value.ty).?;
const union_obj = mod.typeToUnion(typed_value.ty).?;
const field_index = typed_value.ty.unionTagFieldIndex(un.tag.toValue(), mod).?;
assert(union_ty.haveFieldTypes());
const field_ty = union_ty.fields.values()[field_index].ty;
const field_ty = union_obj.field_types.get(ip)[field_index].toType();
if (!field_ty.hasRuntimeBits(mod)) {
try code.appendNTimes(0xaa, math.cast(usize, layout.payload_size) orelse return error.Overflow);
} else {
@@ -593,7 +593,7 @@ pub fn generateSymbol(
if (layout.tag_size > 0 and layout.tag_align < layout.payload_align) {
switch (try generateSymbol(bin_file, src_loc, .{
.ty = union_ty.tag_ty,
.ty = union_obj.enum_tag_ty.toType(),
.val = un.tag.toValue(),
}, code, debug_output, reloc_info)) {
.ok => {},