aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-03-07 18:41:45 -0800
committerGitHub <noreply@github.com>2024-03-07 18:41:45 -0800
commit97aa5f7b8a059f91b78ce7cd70cba0f3aa2c5118 (patch)
tree4e2dc7d8083a24bb01cf8e94e684e3256b7f0a31 /src/codegen
parent377ecc6afb14a112a07c6d2c3570e2b77b12a116 (diff)
parent38331b1cabf86586bdf70c80ed98f74c60305160 (diff)
downloadzig-97aa5f7b8a059f91b78ce7cd70cba0f3aa2c5118.tar.gz
zig-97aa5f7b8a059f91b78ce7cd70cba0f3aa2c5118.zip
Merge pull request #19190 from mlugg/struct-equivalence
compiler: namespace type equivalence based on AST node + captures
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/c.zig223
-rw-r--r--src/codegen/c/type.zig16
-rw-r--r--src/codegen/llvm.zig61
-rw-r--r--src/codegen/spirv.zig20
4 files changed, 163 insertions, 157 deletions
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 60769dc7e5..abbf7501fc 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -1376,70 +1376,24 @@ pub const DeclGen = struct {
}
try writer.writeByte('}');
},
- .struct_type => |struct_type| switch (struct_type.layout) {
- .Auto, .Extern => {
- if (!location.isInitializer()) {
- try writer.writeByte('(');
- try dg.renderType(writer, ty);
- try writer.writeByte(')');
- }
-
- try writer.writeByte('{');
- var empty = true;
- for (0..struct_type.field_types.len) |field_index| {
- const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
- if (struct_type.fieldIsComptime(ip, field_index)) continue;
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
-
- if (!empty) try writer.writeByte(',');
- const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
- .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
- .ty = field_ty.toIntern(),
- .storage = .{ .u64 = bytes[field_index] },
- } }),
- .elems => |elems| elems[field_index],
- .repeated_elem => |elem| elem,
- };
- try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), initializer_type);
-
- empty = false;
- }
- try writer.writeByte('}');
- },
- .Packed => {
- const int_info = ty.intInfo(mod);
-
- const bits = Type.smallestUnsignedBits(int_info.bits - 1);
- const bit_offset_ty = try mod.intType(.unsigned, bits);
-
- var bit_offset: u64 = 0;
- var eff_num_fields: usize = 0;
-
- for (0..struct_type.field_types.len) |field_index| {
- const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
- if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
- eff_num_fields += 1;
- }
-
- if (eff_num_fields == 0) {
- try writer.writeByte('(');
- try dg.renderValue(writer, ty, Value.undef, initializer_type);
- try writer.writeByte(')');
- } else if (ty.bitSize(mod) > 64) {
- // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
- var num_or = eff_num_fields - 1;
- while (num_or > 0) : (num_or -= 1) {
- try writer.writeAll("zig_or_");
- try dg.renderTypeForBuiltinFnName(writer, ty);
+ .struct_type => {
+ const struct_type = ip.loadStructType(ty.toIntern());
+ switch (struct_type.layout) {
+ .Auto, .Extern => {
+ if (!location.isInitializer()) {
try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
}
- var eff_index: usize = 0;
- var needs_closing_paren = false;
+ try writer.writeByte('{');
+ var empty = true;
for (0..struct_type.field_types.len) |field_index| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
+ if (struct_type.fieldIsComptime(ip, field_index)) continue;
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ if (!empty) try writer.writeByte(',');
const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
.bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
.ty = field_ty.toIntern(),
@@ -1448,64 +1402,113 @@ pub const DeclGen = struct {
.elems => |elems| elems[field_index],
.repeated_elem => |elem| elem,
};
- const cast_context = IntCastContext{ .value = .{ .value = Value.fromInterned(field_val) } };
- if (bit_offset != 0) {
- try writer.writeAll("zig_shl_");
- try dg.renderTypeForBuiltinFnName(writer, ty);
- try writer.writeByte('(');
- try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
- try writer.writeAll(", ");
- const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
- try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
- try writer.writeByte(')');
- } else {
- try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
- }
-
- if (needs_closing_paren) try writer.writeByte(')');
- if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
+ try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), initializer_type);
- bit_offset += field_ty.bitSize(mod);
- needs_closing_paren = true;
- eff_index += 1;
+ empty = false;
}
- } else {
- try writer.writeByte('(');
- // a << a_off | b << b_off | c << c_off
- var empty = true;
+ try writer.writeByte('}');
+ },
+ .Packed => {
+ const int_info = ty.intInfo(mod);
+
+ const bits = Type.smallestUnsignedBits(int_info.bits - 1);
+ const bit_offset_ty = try mod.intType(.unsigned, bits);
+
+ var bit_offset: u64 = 0;
+ var eff_num_fields: usize = 0;
+
for (0..struct_type.field_types.len) |field_index| {
const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+ eff_num_fields += 1;
+ }
- if (!empty) try writer.writeAll(" | ");
+ if (eff_num_fields == 0) {
try writer.writeByte('(');
- try dg.renderType(writer, ty);
+ try dg.renderValue(writer, ty, Value.undef, initializer_type);
try writer.writeByte(')');
+ } else if (ty.bitSize(mod) > 64) {
+ // zig_or_u128(zig_or_u128(zig_shl_u128(a, a_off), zig_shl_u128(b, b_off)), zig_shl_u128(c, c_off))
+ var num_or = eff_num_fields - 1;
+ while (num_or > 0) : (num_or -= 1) {
+ try writer.writeAll("zig_or_");
+ try dg.renderTypeForBuiltinFnName(writer, ty);
+ try writer.writeByte('(');
+ }
- const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
- .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
- .ty = field_ty.toIntern(),
- .storage = .{ .u64 = bytes[field_index] },
- } }),
- .elems => |elems| elems[field_index],
- .repeated_elem => |elem| elem,
- };
-
- if (bit_offset != 0) {
- try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), .Other);
- try writer.writeAll(" << ");
- const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
- try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
- } else {
- try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), .Other);
+ var eff_index: usize = 0;
+ var needs_closing_paren = false;
+ for (0..struct_type.field_types.len) |field_index| {
+ const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
+
+ const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
+ .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
+ .ty = field_ty.toIntern(),
+ .storage = .{ .u64 = bytes[field_index] },
+ } }),
+ .elems => |elems| elems[field_index],
+ .repeated_elem => |elem| elem,
+ };
+ const cast_context = IntCastContext{ .value = .{ .value = Value.fromInterned(field_val) } };
+ if (bit_offset != 0) {
+ try writer.writeAll("zig_shl_");
+ try dg.renderTypeForBuiltinFnName(writer, ty);
+ try writer.writeByte('(');
+ try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
+ try writer.writeAll(", ");
+ const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
+ try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
+ try writer.writeByte(')');
+ } else {
+ try dg.renderIntCast(writer, ty, cast_context, field_ty, .FunctionArgument);
+ }
+
+ if (needs_closing_paren) try writer.writeByte(')');
+ if (eff_index != eff_num_fields - 1) try writer.writeAll(", ");
+
+ bit_offset += field_ty.bitSize(mod);
+ needs_closing_paren = true;
+ eff_index += 1;
}
+ } else {
+ try writer.writeByte('(');
+ // a << a_off | b << b_off | c << c_off
+ var empty = true;
+ for (0..struct_type.field_types.len) |field_index| {
+ const field_ty = Type.fromInterned(struct_type.field_types.get(ip)[field_index]);
+ if (!field_ty.hasRuntimeBitsIgnoreComptime(mod)) continue;
- bit_offset += field_ty.bitSize(mod);
- empty = false;
+ if (!empty) try writer.writeAll(" | ");
+ try writer.writeByte('(');
+ try dg.renderType(writer, ty);
+ try writer.writeByte(')');
+
+ const field_val = switch (ip.indexToKey(val.ip_index).aggregate.storage) {
+ .bytes => |bytes| try ip.get(mod.gpa, .{ .int = .{
+ .ty = field_ty.toIntern(),
+ .storage = .{ .u64 = bytes[field_index] },
+ } }),
+ .elems => |elems| elems[field_index],
+ .repeated_elem => |elem| elem,
+ };
+
+ if (bit_offset != 0) {
+ try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), .Other);
+ try writer.writeAll(" << ");
+ const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
+ try dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
+ } else {
+ try dg.renderValue(writer, field_ty, Value.fromInterned(field_val), .Other);
+ }
+
+ bit_offset += field_ty.bitSize(mod);
+ empty = false;
+ }
+ try writer.writeByte(')');
}
- try writer.writeByte(')');
- }
- },
+ },
+ }
},
else => unreachable,
},
@@ -1547,7 +1550,7 @@ pub const DeclGen = struct {
const field_index = mod.unionTagFieldIndex(union_obj, Value.fromInterned(un.tag)).?;
const field_ty = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
- const field_name = union_obj.field_names.get(ip)[field_index];
+ const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
if (union_obj.getLayout(ip) == .Packed) {
if (field_ty.hasRuntimeBits(mod)) {
if (field_ty.isPtrAtRuntime(mod)) {
@@ -5502,7 +5505,7 @@ fn fieldLocation(
.{ .field = .{ .identifier = "payload" } }
else
.begin;
- const field_name = union_obj.field_names.get(ip)[field_index];
+ const field_name = union_obj.loadTagType(ip).names.get(ip)[field_index];
return .{ .field = if (container_ty.unionTagTypeSafety(mod)) |_|
.{ .payload_identifier = ip.stringToSlice(field_name) }
else
@@ -5735,8 +5738,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
else
.{ .identifier = ip.stringToSlice(struct_ty.legacyStructFieldName(extra.field_index, mod)) },
- .union_type => |union_type| field_name: {
- const union_obj = ip.loadUnionType(union_type);
+ .union_type => field_name: {
+ const union_obj = ip.loadUnionType(struct_ty.toIntern());
if (union_obj.flagsPtr(ip).layout == .Packed) {
const operand_lval = if (struct_byval == .constant) blk: {
const operand_local = try f.allocLocal(inst, struct_ty);
@@ -5762,8 +5765,8 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
return local;
} else {
- const name = union_obj.field_names.get(ip)[extra.field_index];
- break :field_name if (union_type.hasTag(ip)) .{
+ const name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
+ break :field_name if (union_obj.hasTag(ip)) .{
.payload_identifier = ip.stringToSlice(name),
} else .{
.identifier = ip.stringToSlice(name),
@@ -7171,7 +7174,7 @@ fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
const union_ty = f.typeOfIndex(inst);
const union_obj = mod.typeToUnion(union_ty).?;
- const field_name = union_obj.field_names.get(ip)[extra.field_index];
+ const field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
const payload_ty = f.typeOf(extra.init);
const payload = try f.resolveInst(extra.init);
try reap(f, inst, &.{extra.init});
diff --git a/src/codegen/c/type.zig b/src/codegen/c/type.zig
index 57b6b97d75..b85daddbda 100644
--- a/src/codegen/c/type.zig
+++ b/src/codegen/c/type.zig
@@ -1507,7 +1507,7 @@ pub const CType = extern union {
if (lookup.isMutable()) {
for (0..switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
- .Union => mod.typeToUnion(ty).?.field_names.len,
+ .Union => mod.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i| {
const field_ty = ty.structFieldType(field_i, mod);
@@ -1589,7 +1589,7 @@ pub const CType = extern union {
var is_packed = false;
for (0..switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
- .Union => mod.typeToUnion(ty).?.field_names.len,
+ .Union => mod.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i| {
const field_ty = ty.structFieldType(field_i, mod);
@@ -1940,7 +1940,7 @@ pub const CType = extern union {
const zig_ty_tag = ty.zigTypeTag(mod);
const fields_len = switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
- .Union => mod.typeToUnion(ty).?.field_names.len,
+ .Union => mod.typeToUnion(ty).?.field_types.len,
else => unreachable,
};
@@ -1967,7 +1967,7 @@ pub const CType = extern union {
else
arena.dupeZ(u8, ip.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.legacyStructFieldName(field_i, mod),
- .Union => mod.typeToUnion(ty).?.field_names.get(ip)[field_i],
+ .Union => ip.loadUnionType(ty.toIntern()).loadTagType(ip).names.get(ip)[field_i],
else => unreachable,
})),
.type = store.set.typeToIndex(field_ty, mod, switch (kind) {
@@ -2097,7 +2097,7 @@ pub const CType = extern union {
var c_field_i: usize = 0;
for (0..switch (zig_ty_tag) {
.Struct => ty.structFieldCount(mod),
- .Union => mod.typeToUnion(ty).?.field_names.len,
+ .Union => mod.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i_usize| {
const field_i: u32 = @intCast(field_i_usize);
@@ -2120,7 +2120,7 @@ pub const CType = extern union {
else
ip.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.legacyStructFieldName(field_i, mod),
- .Union => mod.typeToUnion(ty).?.field_names.get(ip)[field_i],
+ .Union => ip.loadUnionType(ty.toIntern()).loadTagType(ip).names.get(ip)[field_i],
else => unreachable,
}),
mem.span(c_field.name),
@@ -2226,7 +2226,7 @@ pub const CType = extern union {
const zig_ty_tag = ty.zigTypeTag(mod);
for (0..switch (ty.zigTypeTag(mod)) {
.Struct => ty.structFieldCount(mod),
- .Union => mod.typeToUnion(ty).?.field_names.len,
+ .Union => mod.typeToUnion(ty).?.field_types.len,
else => unreachable,
}) |field_i_usize| {
const field_i: u32 = @intCast(field_i_usize);
@@ -2245,7 +2245,7 @@ pub const CType = extern union {
else
mod.intern_pool.stringToSlice(switch (zig_ty_tag) {
.Struct => ty.legacyStructFieldName(field_i, mod),
- .Union => mod.typeToUnion(ty).?.field_names.get(ip)[field_i],
+ .Union => ip.loadUnionType(ty.toIntern()).loadTagType(ip).names.get(ip)[field_i],
else => unreachable,
}));
autoHash(hasher, AlignAs.fieldAlign(ty, field_i, mod).@"align");
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index a7e2815e73..8f69dbc7e9 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -1997,7 +1997,7 @@ pub const Object = struct {
return debug_enum_type;
}
- const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
+ const enum_type = ip.loadEnumType(ty.toIntern());
const enumerators = try gpa.alloc(Builder.Metadata, enum_type.names.len);
defer gpa.free(enumerators);
@@ -2507,8 +2507,8 @@ pub const Object = struct {
try o.debug_type_map.put(gpa, ty, debug_struct_type);
return debug_struct_type;
},
- .struct_type => |struct_type| {
- if (!struct_type.haveFieldTypes(ip)) {
+ .struct_type => {
+ if (!ip.loadStructType(ty.toIntern()).haveFieldTypes(ip)) {
// This can happen if a struct type makes it all the way to
// flush() without ever being instantiated or referenced (even
// via pointer). The only reason we are hearing about it now is
@@ -2597,15 +2597,14 @@ pub const Object = struct {
const name = try o.allocTypeName(ty);
defer gpa.free(name);
- const union_type = ip.indexToKey(ty.toIntern()).union_type;
+ const union_type = ip.loadUnionType(ty.toIntern());
if (!union_type.haveFieldTypes(ip) or !ty.hasRuntimeBitsIgnoreComptime(mod)) {
const debug_union_type = try o.makeEmptyNamespaceDebugType(owner_decl_index);
try o.debug_type_map.put(gpa, ty, debug_union_type);
return debug_union_type;
}
- const union_obj = ip.loadUnionType(union_type);
- const layout = mod.getUnionLayout(union_obj);
+ const layout = mod.getUnionLayout(union_type);
const debug_fwd_ref = try o.builder.debugForwardReference();
@@ -2622,7 +2621,7 @@ pub const Object = struct {
ty.abiSize(mod) * 8,
ty.abiAlignment(mod).toByteUnits(0) * 8,
try o.builder.debugTuple(
- &.{try o.lowerDebugType(Type.fromInterned(union_obj.enum_tag_ty))},
+ &.{try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty))},
),
);
@@ -2636,21 +2635,23 @@ pub const Object = struct {
var fields: std.ArrayListUnmanaged(Builder.Metadata) = .{};
defer fields.deinit(gpa);
- try fields.ensureUnusedCapacity(gpa, union_obj.field_names.len);
+ try fields.ensureUnusedCapacity(gpa, union_type.loadTagType(ip).names.len);
const debug_union_fwd_ref = if (layout.tag_size == 0)
debug_fwd_ref
else
try o.builder.debugForwardReference();
- for (0..union_obj.field_names.len) |field_index| {
- const field_ty = union_obj.field_types.get(ip)[field_index];
+ const tag_type = union_type.loadTagType(ip);
+
+ for (0..tag_type.names.len) |field_index| {
+ const field_ty = union_type.field_types.get(ip)[field_index];
if (!Type.fromInterned(field_ty).hasRuntimeBitsIgnoreComptime(mod)) continue;
const field_size = Type.fromInterned(field_ty).abiSize(mod);
- const field_align = mod.unionFieldNormalAlignment(union_obj, @intCast(field_index));
+ const field_align = mod.unionFieldNormalAlignment(union_type, @intCast(field_index));
- const field_name = union_obj.field_names.get(ip)[field_index];
+ const field_name = tag_type.names.get(ip)[field_index];
fields.appendAssumeCapacity(try o.builder.debugMemberType(
try o.builder.metadataString(ip.stringToSlice(field_name)),
.none, // File
@@ -2706,7 +2707,7 @@ pub const Object = struct {
.none, // File
debug_fwd_ref,
0, // Line
- try o.lowerDebugType(Type.fromInterned(union_obj.enum_tag_ty)),
+ try o.lowerDebugType(Type.fromInterned(union_type.enum_tag_ty)),
layout.tag_size * 8,
layout.tag_align.toByteUnits(0) * 8,
tag_offset * 8,
@@ -3321,9 +3322,11 @@ pub const Object = struct {
return o.builder.structType(.normal, fields[0..fields_len]);
},
.simple_type => unreachable,
- .struct_type => |struct_type| {
+ .struct_type => {
if (o.type_map.get(t.toIntern())) |value| return value;
+ const struct_type = ip.loadStructType(t.toIntern());
+
if (struct_type.layout == .Packed) {
const int_ty = try o.lowerType(Type.fromInterned(struct_type.backingIntType(ip).*));
try o.type_map.put(o.gpa, t.toIntern(), int_ty);
@@ -3468,10 +3471,10 @@ pub const Object = struct {
}
return o.builder.structType(.normal, llvm_field_types.items);
},
- .union_type => |union_type| {
+ .union_type => {
if (o.type_map.get(t.toIntern())) |value| return value;
- const union_obj = ip.loadUnionType(union_type);
+ const union_obj = ip.loadUnionType(t.toIntern());
const layout = mod.getUnionLayout(union_obj);
if (union_obj.flagsPtr(ip).layout == .Packed) {
@@ -3545,17 +3548,16 @@ pub const Object = struct {
);
return ty;
},
- .opaque_type => |opaque_type| {
+ .opaque_type => {
const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
if (!gop.found_existing) {
- const name = try o.builder.string(ip.stringToSlice(
- try mod.opaqueFullyQualifiedName(opaque_type),
- ));
+ const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);
+ const name = try o.builder.string(ip.stringToSlice(try decl.fullyQualifiedName(mod)));
gop.value_ptr.* = try o.builder.opaqueType(name);
}
return gop.value_ptr.*;
},
- .enum_type => |enum_type| try o.lowerType(Type.fromInterned(enum_type.tag_ty)),
+ .enum_type => try o.lowerType(Type.fromInterned(ip.loadEnumType(t.toIntern()).tag_ty)),
.func_type => |func_type| try o.lowerTypeFn(func_type),
.error_set_type, .inferred_error_set_type => try o.errorIntType(),
// values, not types
@@ -4032,7 +4034,8 @@ pub const Object = struct {
else
struct_ty, vals);
},
- .struct_type => |struct_type| {
+ .struct_type => {
+ const struct_type = ip.loadStructType(ty.toIntern());
assert(struct_type.haveLayout(ip));
const struct_ty = try o.lowerType(ty);
if (struct_type.layout == .Packed) {
@@ -4596,7 +4599,7 @@ pub const Object = struct {
fn getEnumTagNameFunction(o: *Object, enum_ty: Type) !Builder.Function.Index {
const zcu = o.module;
const ip = &zcu.intern_pool;
- const enum_type = ip.indexToKey(enum_ty.toIntern()).enum_type;
+ const enum_type = ip.loadEnumType(enum_ty.toIntern());
// TODO: detect when the type changes and re-emit this function.
const gop = try o.decl_map.getOrPut(o.gpa, enum_type.decl);
@@ -9620,7 +9623,7 @@ pub const FuncGen = struct {
fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !Builder.Function.Index {
const o = self.dg.object;
const zcu = o.module;
- const enum_type = zcu.intern_pool.indexToKey(enum_ty.toIntern()).enum_type;
+ const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());
// TODO: detect when the type changes and re-emit this function.
const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
@@ -10092,7 +10095,7 @@ pub const FuncGen = struct {
const tag_int = blk: {
const tag_ty = union_ty.unionTagTypeHypothetical(mod);
- const union_field_name = union_obj.field_names.get(ip)[extra.field_index];
+ const union_field_name = union_obj.loadTagType(ip).names.get(ip)[extra.field_index];
const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;
const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);
@@ -11154,7 +11157,8 @@ fn lowerSystemVFnRetTy(o: *Object, fn_info: InternPool.Key.FuncType) Allocator.E
if (first_non_integer == null or classes[first_non_integer.?] == .none) {
assert(first_non_integer orelse classes.len == types_index);
switch (ip.indexToKey(return_type.toIntern())) {
- .struct_type => |struct_type| {
+ .struct_type => {
+ const struct_type = ip.loadStructType(return_type.toIntern());
assert(struct_type.haveLayout(ip));
const size: u64 = struct_type.size(ip).*;
assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
@@ -11446,7 +11450,8 @@ const ParamTypeIterator = struct {
return .byref;
}
switch (ip.indexToKey(ty.toIntern())) {
- .struct_type => |struct_type| {
+ .struct_type => {
+ const struct_type = ip.loadStructType(ty.toIntern());
assert(struct_type.haveLayout(ip));
const size: u64 = struct_type.size(ip).*;
assert((std.math.divCeil(u64, size, 8) catch unreachable) == types_index);
@@ -11562,7 +11567,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
}
return false;
},
- .struct_type => |s| s,
+ .struct_type => ip.loadStructType(ty.toIntern()),
else => unreachable,
};
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index 59cbb9d2d3..e95ffee5c1 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -1528,7 +1528,7 @@ const DeclGen = struct {
try self.type_map.put(self.gpa, ty.toIntern(), .{ .ty_ref = ty_ref });
return ty_ref;
},
- .struct_type => |struct_type| struct_type,
+ .struct_type => ip.loadStructType(ty.toIntern()),
else => unreachable,
};
@@ -3633,7 +3633,8 @@ const DeclGen = struct {
index += 1;
}
},
- .struct_type => |struct_type| {
+ .struct_type => {
+ const struct_type = ip.loadStructType(result_ty.toIntern());
var it = struct_type.iterateRuntimeOrder(ip);
for (elements, 0..) |element, i| {
const field_index = it.next().?;
@@ -3901,36 +3902,33 @@ const DeclGen = struct {
const mod = self.module;
const ip = &mod.intern_pool;
const union_ty = mod.typeToUnion(ty).?;
+ const tag_ty = Type.fromInterned(union_ty.enum_tag_ty);
if (union_ty.getLayout(ip) == .Packed) {
unreachable; // TODO
}
- const maybe_tag_ty = ty.unionTagTypeSafety(mod);
const layout = self.unionLayout(ty);
const tag_int = if (layout.tag_size != 0) blk: {
- const tag_ty = maybe_tag_ty.?;
- const union_field_name = union_ty.field_names.get(ip)[active_field];
- const enum_field_index = tag_ty.enumFieldIndex(union_field_name, mod).?;
- const tag_val = try mod.enumValueFieldIndex(tag_ty, enum_field_index);
+ const tag_val = try mod.enumValueFieldIndex(tag_ty, active_field);
const tag_int_val = try tag_val.intFromEnum(tag_ty, mod);
break :blk tag_int_val.toUnsignedInt(mod);
} else 0;
if (!layout.has_payload) {
- const tag_ty_ref = try self.resolveType(maybe_tag_ty.?, .direct);
+ const tag_ty_ref = try self.resolveType(tag_ty, .direct);
return try self.constInt(tag_ty_ref, tag_int);
}
const tmp_id = try self.alloc(ty, .{ .storage_class = .Function });
if (layout.tag_size != 0) {
- const tag_ty_ref = try self.resolveType(maybe_tag_ty.?, .direct);
- const tag_ptr_ty_ref = try self.ptrType(maybe_tag_ty.?, .Function);
+ const tag_ty_ref = try self.resolveType(tag_ty, .direct);
+ const tag_ptr_ty_ref = try self.ptrType(tag_ty, .Function);
const ptr_id = try self.accessChain(tag_ptr_ty_ref, tmp_id, &.{@as(u32, @intCast(layout.tag_index))});
const tag_id = try self.constInt(tag_ty_ref, tag_int);
- try self.store(maybe_tag_ty.?, ptr_id, tag_id, .{});
+ try self.store(tag_ty, ptr_id, tag_id, .{});
}
const payload_ty = Type.fromInterned(union_ty.field_types.get(ip)[active_field]);