diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-03-07 18:41:45 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-07 18:41:45 -0800 |
| commit | 97aa5f7b8a059f91b78ce7cd70cba0f3aa2c5118 (patch) | |
| tree | 4e2dc7d8083a24bb01cf8e94e684e3256b7f0a31 /src/codegen | |
| parent | 377ecc6afb14a112a07c6d2c3570e2b77b12a116 (diff) | |
| parent | 38331b1cabf86586bdf70c80ed98f74c60305160 (diff) | |
| download | zig-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.zig | 223 | ||||
| -rw-r--r-- | src/codegen/c/type.zig | 16 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 61 | ||||
| -rw-r--r-- | src/codegen/spirv.zig | 20 |
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]); |
