authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-20 17:55:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:54-07:00
log7e19c9566860e78ad536aaa678af8c32531fade9
treed6e90d6c1cf0d13bee52b8107804837658486927
parent65d65f5dda144d76ea9bbd82b2b5aacb09d7ae34

Sema: move `inferred_alloc_const/mut_type` to InternPool

Now, all types are migrated to use `InternPool`. The `Type.Tag` enum is deleted in this commit.

11 files changed, 594 insertions(+), 866 deletions(-)

src/Air.zig+2
......@@ -905,6 +905,8 @@ pub const Inst = struct {
905905 const_slice_u8_sentinel_0_type = @enumToInt(InternPool.Index.const_slice_u8_sentinel_0_type),
906906 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
907907 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
908 inferred_alloc_const_type = @enumToInt(InternPool.Index.inferred_alloc_const_type),
909 inferred_alloc_mut_type = @enumToInt(InternPool.Index.inferred_alloc_mut_type),
908910 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),
909911 undef = @enumToInt(InternPool.Index.undef),
910912 zero = @enumToInt(InternPool.Index.zero),
src/InternPool.zig+13-4
......@@ -959,6 +959,8 @@ pub const Index = enum(u32) {
959959 const_slice_u8_sentinel_0_type,
960960 anyerror_void_error_union_type,
961961 generic_poison_type,
962 inferred_alloc_const_type,
963 inferred_alloc_mut_type,
962964 /// `@TypeOf(.{})`
963965 empty_struct_type,
964966
......@@ -1009,10 +1011,7 @@ pub const Index = enum(u32) {
10091011
10101012 pub fn toType(i: Index) @import("type.zig").Type {
10111013 assert(i != .none);
1012 return .{
1013 .ip_index = i,
1014 .legacy = undefined,
1015 };
1014 return .{ .ip_index = i };
10161015 }
10171016
10181017 pub fn toValue(i: Index) @import("value.zig").Value {
......@@ -1195,6 +1194,10 @@ pub const static_keys = [_]Key{
11951194
11961195 // generic_poison_type
11971196 .{ .simple_type = .generic_poison },
1197 // inferred_alloc_const_type
1198 .{ .simple_type = .inferred_alloc_const },
1199 // inferred_alloc_mut_type
1200 .{ .simple_type = .inferred_alloc_mut },
11981201
11991202 // empty_struct_type
12001203 .{ .anon_struct_type = .{
......@@ -1568,6 +1571,12 @@ pub const SimpleType = enum(u32) {
15681571 type_info,
15691572
15701573 generic_poison,
1574 /// TODO: remove this from `SimpleType`; instead make it only a special `Index` tag like
1575 /// `var_args_param_type`.
1576 inferred_alloc_const,
1577 /// TODO: remove this from `SimpleType`; instead make it only a special `Index` tag like
1578 /// `var_args_param_type`.
1579 inferred_alloc_mut,
15711580};
15721581
15731582pub const SimpleValue = enum(u32) {
src/Module.zig+1-1
......@@ -6818,7 +6818,7 @@ pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type {
68186818}
68196819
68206820pub fn adjustPtrTypeChild(mod: *Module, ptr_ty: Type, new_child: Type) Allocator.Error!Type {
6821 const info = ptr_ty.ptrInfoIp(mod.intern_pool);
6821 const info = Type.ptrInfoIp(mod.intern_pool, ptr_ty.toIntern());
68226822 return mod.ptrType(.{
68236823 .elem_type = new_child.toIntern(),
68246824
src/Sema.zig+51-45
......@@ -904,10 +904,10 @@ fn analyzeBodyInner(
904904 const air_inst: Air.Inst.Ref = switch (tags[inst]) {
905905 // zig fmt: off
906906 .alloc => try sema.zirAlloc(block, inst),
907 .alloc_inferred => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_const)),
908 .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, Type.initTag(.inferred_alloc_mut)),
909 .alloc_inferred_comptime => try sema.zirAllocInferredComptime(inst, Type.initTag(.inferred_alloc_const)),
910 .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(inst, Type.initTag(.inferred_alloc_mut)),
907 .alloc_inferred => try sema.zirAllocInferred(block, inst, .{ .ip_index = .inferred_alloc_const_type }),
908 .alloc_inferred_mut => try sema.zirAllocInferred(block, inst, .{ .ip_index = .inferred_alloc_mut_type }),
909 .alloc_inferred_comptime => try sema.zirAllocInferredComptime(inst, .{ .ip_index = .inferred_alloc_const_type }),
910 .alloc_inferred_comptime_mut => try sema.zirAllocInferredComptime(inst, .{ .ip_index = .inferred_alloc_mut_type }),
911911 .alloc_mut => try sema.zirAllocMut(block, inst),
912912 .alloc_comptime_mut => try sema.zirAllocComptime(block, inst),
913913 .make_ptr_const => try sema.zirMakePtrConst(block, inst),
......@@ -3471,9 +3471,9 @@ fn zirAllocExtended(
34713471 } else 0;
34723472
34733473 const inferred_alloc_ty = if (small.is_const)
3474 Type.initTag(.inferred_alloc_const)
3474 Type{ .ip_index = .inferred_alloc_const_type }
34753475 else
3476 Type.initTag(.inferred_alloc_mut);
3476 Type{ .ip_index = .inferred_alloc_mut_type };
34773477
34783478 if (block.is_comptime or small.is_comptime) {
34793479 if (small.has_type) {
......@@ -3707,9 +3707,10 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com
37073707 assert(sema.air_instructions.items(.tag)[ptr_inst] == .constant);
37083708 const value_index = sema.air_instructions.items(.data)[ptr_inst].ty_pl.payload;
37093709 const ptr_val = sema.air_values.items[value_index];
3710 const var_is_mut = switch (sema.typeOf(ptr).tag()) {
3711 .inferred_alloc_const => false,
3712 .inferred_alloc_mut => true,
3710 const var_is_mut = switch (sema.typeOf(ptr).toIntern()) {
3711 .inferred_alloc_const_type => false,
3712 .inferred_alloc_mut_type => true,
3713 else => unreachable,
37133714 };
37143715 const target = sema.mod.getTarget();
37153716
......@@ -7451,7 +7452,7 @@ fn instantiateGenericCall(
74517452 };
74527453 arg_val.hashUncoerced(arg_ty, &hasher, mod);
74537454 if (is_anytype) {
7454 arg_ty.hashWithHasher(&hasher, mod);
7455 std.hash.autoHash(&hasher, arg_ty.toIntern());
74557456 generic_args[i] = .{
74567457 .ty = arg_ty,
74577458 .val = arg_val,
......@@ -7465,7 +7466,7 @@ fn instantiateGenericCall(
74657466 };
74667467 }
74677468 } else if (is_anytype) {
7468 arg_ty.hashWithHasher(&hasher, mod);
7469 std.hash.autoHash(&hasher, arg_ty.toIntern());
74697470 generic_args[i] = .{
74707471 .ty = arg_ty,
74717472 .val = Value.generic_poison,
......@@ -8233,7 +8234,7 @@ fn zirEnumLiteral(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
82338234 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
82348235 const duped_name = try sema.arena.dupe(u8, inst_data.get(sema.code));
82358236 return sema.addConstant(
8236 .{ .ip_index = .enum_literal_type, .legacy = undefined },
8237 .{ .ip_index = .enum_literal_type },
82378238 try Value.Tag.enum_literal.create(sema.arena, duped_name),
82388239 );
82398240}
......@@ -13278,9 +13279,12 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1327813279 const rhs_val = maybe_rhs_val orelse unreachable;
1327913280 const rem = lhs_val.floatRem(rhs_val, resolved_type, sema.arena, mod) catch unreachable;
1328013281 if (!rem.compareAllWithZero(.eq, mod)) {
13281 return sema.fail(block, src, "ambiguous coercion of division operands '{s}' and '{s}'; non-zero remainder '{}'", .{
13282 @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()), rem.fmtValue(resolved_type, sema.mod),
13283 });
13282 return sema.fail(
13283 block,
13284 src,
13285 "ambiguous coercion of division operands '{}' and '{}'; non-zero remainder '{}'",
13286 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod), rem.fmtValue(resolved_type, mod) },
13287 );
1328413288 }
1328513289 }
1328613290
......@@ -13386,7 +13390,12 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins
1338613390
1338713391 const air_tag = if (is_int) blk: {
1338813392 if (lhs_ty.isSignedInt(mod) or rhs_ty.isSignedInt(mod)) {
13389 return sema.fail(block, src, "division with '{s}' and '{s}': signed integers must use @divTrunc, @divFloor, or @divExact", .{ @tagName(lhs_ty.tag()), @tagName(rhs_ty.tag()) });
13393 return sema.fail(
13394 block,
13395 src,
13396 "division with '{}' and '{}': signed integers must use @divTrunc, @divFloor, or @divExact",
13397 .{ lhs_ty.fmt(mod), rhs_ty.fmt(mod) },
13398 );
1339013399 }
1339113400 break :blk Air.Inst.Tag.div_trunc;
1339213401 } else switch (block.float_mode) {
......@@ -23367,7 +23376,7 @@ fn validateRunTimeType(
2336723376 };
2336823377}
2336923378
23370const TypeSet = std.HashMapUnmanaged(Type, void, Type.HashContext64, std.hash_map.default_max_load_percentage);
23379const TypeSet = std.AutoHashMapUnmanaged(InternPool.Index, void);
2337123380
2337223381fn explainWhyTypeIsComptime(
2337323382 sema: *Sema,
......@@ -23453,7 +23462,7 @@ fn explainWhyTypeIsComptimeInner(
2345323462 },
2345423463
2345523464 .Struct => {
23456 if ((try type_set.getOrPutContext(sema.gpa, ty, .{ .mod = mod })).found_existing) return;
23465 if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return;
2345723466
2345823467 if (mod.typeToStruct(ty)) |struct_obj| {
2345923468 for (struct_obj.fields.values(), 0..) |field, i| {
......@@ -23472,7 +23481,7 @@ fn explainWhyTypeIsComptimeInner(
2347223481 },
2347323482
2347423483 .Union => {
23475 if ((try type_set.getOrPutContext(sema.gpa, ty, .{ .mod = mod })).found_existing) return;
23484 if ((try type_set.getOrPut(sema.gpa, ty.toIntern())).found_existing) return;
2347623485
2347723486 if (mod.typeToUnion(ty)) |union_obj| {
2347823487 for (union_obj.fields.values(), 0..) |field, i| {
......@@ -27459,8 +27468,8 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref {
2745927468 // different behavior depending on whether the types were inferred.
2746027469 // Something seems wrong here.
2746127470 if (prev_ptr_ty.ip_index == .none) {
27462 if (prev_ptr_ty.tag() == .inferred_alloc_mut) return null;
27463 if (prev_ptr_ty.tag() == .inferred_alloc_const) return null;
27471 if (prev_ptr_ty.ip_index == .inferred_alloc_mut_type) return null;
27472 if (prev_ptr_ty.ip_index == .inferred_alloc_const_type) return null;
2746427473 }
2746527474
2746627475 const prev_ptr_child_ty = prev_ptr_ty.childType(mod);
......@@ -31677,6 +31686,9 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3167731686 .enum_literal,
3167831687 .type_info,
3167931688 => true,
31689
31690 .inferred_alloc_const => unreachable,
31691 .inferred_alloc_mut => unreachable,
3168031692 },
3168131693 .struct_type => |struct_type| {
3168231694 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return false;
......@@ -31931,6 +31943,8 @@ pub fn resolveTypeFields(sema: *Sema, ty: Type) CompileError!Type {
3193131943 .bool_false => unreachable,
3193231944 .empty_struct => unreachable,
3193331945 .generic_poison => unreachable,
31946 .inferred_alloc_const_type => unreachable,
31947 .inferred_alloc_mut_type => unreachable,
3193431948
3193531949 .type_info_type => return sema.getBuiltinType("Type"),
3193631950 .extern_options_type => return sema.getBuiltinType("ExternOptions"),
......@@ -33032,16 +33046,9 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
3303233046/// TODO assert the return value matches `ty.onePossibleValue`
3303333047pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3303433048 const mod = sema.mod;
33035
33036 switch (ty.ip_index) {
33037 .empty_struct_type => return Value.empty_struct,
33038
33039 .none => switch (ty.tag()) {
33040 .inferred_alloc_const => unreachable,
33041 .inferred_alloc_mut => unreachable,
33042 },
33043
33044 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
33049 return switch (ty.ip_index) {
33050 .empty_struct_type => Value.empty_struct,
33051 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3304533052 .int_type => |int_type| {
3304633053 if (int_type.bits == 0) {
3304733054 return try mod.intValue(ty, 0);
......@@ -33123,6 +33130,8 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3312333130 .undefined => Value.undef,
3312433131
3312533132 .generic_poison => return error.GenericPoison,
33133 .inferred_alloc_const => unreachable,
33134 .inferred_alloc_mut => unreachable,
3312633135 },
3312733136 .struct_type => |struct_type| {
3312833137 const resolved_ty = try sema.resolveTypeFields(ty);
......@@ -33245,7 +33254,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3324533254 .enum_tag => unreachable,
3324633255 .aggregate => unreachable,
3324733256 },
33248 }
33257 };
3324933258}
3325033259
3325133260/// Returns the type of the AIR instruction.
......@@ -33563,16 +33572,15 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError
3356333572/// This logic must be kept in sync with `Type.isPtrLikeOptional`.
3356433573fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3356533574 const mod = sema.mod;
33566
33567 if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) {
33575 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3356833576 .ptr_type => |ptr_type| switch (ptr_type.size) {
33569 .Slice => return null,
33570 .C => return ptr_type.elem_type.toType(),
33571 .One, .Many => return ty,
33577 .Slice => null,
33578 .C => ptr_type.elem_type.toType(),
33579 .One, .Many => ty,
3357233580 },
3357333581 .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) {
3357433582 .ptr_type => |ptr_type| switch (ptr_type.size) {
33575 .Slice, .C => return null,
33583 .Slice, .C => null,
3357633584 .Many, .One => {
3357733585 if (ptr_type.is_allowzero) return null;
3357833586
......@@ -33585,15 +33593,10 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3358533593 return payload_ty;
3358633594 },
3358733595 },
33588 else => return null,
33596 else => null,
3358933597 },
33590 else => return null,
33598 else => null,
3359133599 };
33592
33593 switch (ty.tag()) {
33594 .inferred_alloc_const => unreachable,
33595 .inferred_alloc_mut => unreachable,
33596 }
3359733600}
3359833601
3359933602/// `generic_poison` will return false.
......@@ -33677,6 +33680,9 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3367733680 .enum_literal,
3367833681 .type_info,
3367933682 => true,
33683
33684 .inferred_alloc_const => unreachable,
33685 .inferred_alloc_mut => unreachable,
3368033686 },
3368133687 .struct_type => |struct_type| {
3368233688 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse return false;
src/Zir.zig+2
......@@ -2112,6 +2112,8 @@ pub const Inst = struct {
21122112 const_slice_u8_sentinel_0_type = @enumToInt(InternPool.Index.const_slice_u8_sentinel_0_type),
21132113 anyerror_void_error_union_type = @enumToInt(InternPool.Index.anyerror_void_error_union_type),
21142114 generic_poison_type = @enumToInt(InternPool.Index.generic_poison_type),
2115 inferred_alloc_const_type = @enumToInt(InternPool.Index.inferred_alloc_const_type),
2116 inferred_alloc_mut_type = @enumToInt(InternPool.Index.inferred_alloc_mut_type),
21152117 empty_struct_type = @enumToInt(InternPool.Index.empty_struct_type),
21162118 undef = @enumToInt(InternPool.Index.undef),
21172119 zero = @enumToInt(InternPool.Index.zero),
src/codegen/c.zig+94-99
......@@ -5367,116 +5367,111 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
53675367 // Ensure complete type definition is visible before accessing fields.
53685368 _ = try f.typeToIndex(struct_ty, .complete);
53695369
5370 const field_name: CValue = switch (struct_ty.ip_index) {
5371 .none => switch (struct_ty.tag()) {
5372 else => unreachable,
5373 },
5374 else => switch (mod.intern_pool.indexToKey(struct_ty.ip_index)) {
5375 .struct_type => switch (struct_ty.containerLayout(mod)) {
5376 .Auto, .Extern => if (struct_ty.isSimpleTuple(mod))
5377 .{ .field = extra.field_index }
5378 else
5379 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
5380 .Packed => {
5381 const struct_obj = mod.typeToStruct(struct_ty).?;
5382 const int_info = struct_ty.intInfo(mod);
5383
5384 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
5370 const field_name: CValue = switch (mod.intern_pool.indexToKey(struct_ty.ip_index)) {
5371 .struct_type => switch (struct_ty.containerLayout(mod)) {
5372 .Auto, .Extern => if (struct_ty.isSimpleTuple(mod))
5373 .{ .field = extra.field_index }
5374 else
5375 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
5376 .Packed => {
5377 const struct_obj = mod.typeToStruct(struct_ty).?;
5378 const int_info = struct_ty.intInfo(mod);
53855379
5386 const bit_offset = struct_obj.packedFieldBitOffset(mod, extra.field_index);
5387 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
5380 const bit_offset_ty = try mod.intType(.unsigned, Type.smallestUnsignedBits(int_info.bits - 1));
53885381
5389 const field_int_signedness = if (inst_ty.isAbiInt(mod))
5390 inst_ty.intInfo(mod).signedness
5391 else
5392 .unsigned;
5393 const field_int_ty = try mod.intType(field_int_signedness, @intCast(u16, inst_ty.bitSize(mod)));
5382 const bit_offset = struct_obj.packedFieldBitOffset(mod, extra.field_index);
5383 const bit_offset_val = try mod.intValue(bit_offset_ty, bit_offset);
53945384
5395 const temp_local = try f.allocLocal(inst, field_int_ty);
5396 try f.writeCValue(writer, temp_local, .Other);
5397 try writer.writeAll(" = zig_wrap_");
5398 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);
5399 try writer.writeAll("((");
5400 try f.renderType(writer, field_int_ty);
5385 const field_int_signedness = if (inst_ty.isAbiInt(mod))
5386 inst_ty.intInfo(mod).signedness
5387 else
5388 .unsigned;
5389 const field_int_ty = try mod.intType(field_int_signedness, @intCast(u16, inst_ty.bitSize(mod)));
5390
5391 const temp_local = try f.allocLocal(inst, field_int_ty);
5392 try f.writeCValue(writer, temp_local, .Other);
5393 try writer.writeAll(" = zig_wrap_");
5394 try f.object.dg.renderTypeForBuiltinFnName(writer, field_int_ty);
5395 try writer.writeAll("((");
5396 try f.renderType(writer, field_int_ty);
5397 try writer.writeByte(')');
5398 const cant_cast = int_info.bits > 64;
5399 if (cant_cast) {
5400 if (field_int_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
5401 try writer.writeAll("zig_lo_");
5402 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5403 try writer.writeByte('(');
5404 }
5405 if (bit_offset > 0) {
5406 try writer.writeAll("zig_shr_");
5407 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5408 try writer.writeByte('(');
5409 }
5410 try f.writeCValue(writer, struct_byval, .Other);
5411 if (bit_offset > 0) {
5412 try writer.writeAll(", ");
5413 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
54015414 try writer.writeByte(')');
5402 const cant_cast = int_info.bits > 64;
5403 if (cant_cast) {
5404 if (field_int_ty.bitSize(mod) > 64) return f.fail("TODO: C backend: implement casting between types > 64 bits", .{});
5405 try writer.writeAll("zig_lo_");
5406 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5407 try writer.writeByte('(');
5408 }
5409 if (bit_offset > 0) {
5410 try writer.writeAll("zig_shr_");
5411 try f.object.dg.renderTypeForBuiltinFnName(writer, struct_ty);
5412 try writer.writeByte('(');
5413 }
5414 try f.writeCValue(writer, struct_byval, .Other);
5415 if (bit_offset > 0) {
5416 try writer.writeAll(", ");
5417 try f.object.dg.renderValue(writer, bit_offset_ty, bit_offset_val, .FunctionArgument);
5418 try writer.writeByte(')');
5419 }
5420 if (cant_cast) try writer.writeByte(')');
5421 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
5422 try writer.writeAll(");\n");
5423 if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;
5415 }
5416 if (cant_cast) try writer.writeByte(')');
5417 try f.object.dg.renderBuiltinInfo(writer, field_int_ty, .bits);
5418 try writer.writeAll(");\n");
5419 if (inst_ty.eql(field_int_ty, f.object.dg.module)) return temp_local;
54245420
5425 const local = try f.allocLocal(inst, inst_ty);
5426 try writer.writeAll("memcpy(");
5427 try f.writeCValue(writer, .{ .local_ref = local.new_local }, .FunctionArgument);
5428 try writer.writeAll(", ");
5429 try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
5430 try writer.writeAll(", sizeof(");
5431 try f.renderType(writer, inst_ty);
5432 try writer.writeAll("));\n");
5433 try freeLocal(f, inst, temp_local.new_local, 0);
5434 return local;
5435 },
5421 const local = try f.allocLocal(inst, inst_ty);
5422 try writer.writeAll("memcpy(");
5423 try f.writeCValue(writer, .{ .local_ref = local.new_local }, .FunctionArgument);
5424 try writer.writeAll(", ");
5425 try f.writeCValue(writer, .{ .local_ref = temp_local.new_local }, .FunctionArgument);
5426 try writer.writeAll(", sizeof(");
5427 try f.renderType(writer, inst_ty);
5428 try writer.writeAll("));\n");
5429 try freeLocal(f, inst, temp_local.new_local, 0);
5430 return local;
54365431 },
5432 },
54375433
5438 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0)
5439 .{ .field = extra.field_index }
5440 else
5441 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
5434 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 0)
5435 .{ .field = extra.field_index }
5436 else
5437 .{ .identifier = struct_ty.structFieldName(extra.field_index, mod) },
5438
5439 .union_type => |union_type| field_name: {
5440 const union_obj = mod.unionPtr(union_type.index);
5441 if (union_obj.layout == .Packed) {
5442 const operand_lval = if (struct_byval == .constant) blk: {
5443 const operand_local = try f.allocLocal(inst, struct_ty);
5444 try f.writeCValue(writer, operand_local, .Other);
5445 try writer.writeAll(" = ");
5446 try f.writeCValue(writer, struct_byval, .Initializer);
5447 try writer.writeAll(";\n");
5448 break :blk operand_local;
5449 } else struct_byval;
54425450
5443 .union_type => |union_type| field_name: {
5444 const union_obj = mod.unionPtr(union_type.index);
5445 if (union_obj.layout == .Packed) {
5446 const operand_lval = if (struct_byval == .constant) blk: {
5447 const operand_local = try f.allocLocal(inst, struct_ty);
5448 try f.writeCValue(writer, operand_local, .Other);
5449 try writer.writeAll(" = ");
5450 try f.writeCValue(writer, struct_byval, .Initializer);
5451 try writer.writeAll(";\n");
5452 break :blk operand_local;
5453 } else struct_byval;
5454
5455 const local = try f.allocLocal(inst, inst_ty);
5456 try writer.writeAll("memcpy(&");
5457 try f.writeCValue(writer, local, .Other);
5458 try writer.writeAll(", &");
5459 try f.writeCValue(writer, operand_lval, .Other);
5460 try writer.writeAll(", sizeof(");
5461 try f.renderType(writer, inst_ty);
5462 try writer.writeAll("));\n");
5463
5464 if (struct_byval == .constant) {
5465 try freeLocal(f, inst, operand_lval.new_local, 0);
5466 }
5451 const local = try f.allocLocal(inst, inst_ty);
5452 try writer.writeAll("memcpy(&");
5453 try f.writeCValue(writer, local, .Other);
5454 try writer.writeAll(", &");
5455 try f.writeCValue(writer, operand_lval, .Other);
5456 try writer.writeAll(", sizeof(");
5457 try f.renderType(writer, inst_ty);
5458 try writer.writeAll("));\n");
54675459
5468 return local;
5469 } else {
5470 const name = union_obj.fields.keys()[extra.field_index];
5471 break :field_name if (union_type.hasTag()) .{
5472 .payload_identifier = name,
5473 } else .{
5474 .identifier = name,
5475 };
5460 if (struct_byval == .constant) {
5461 try freeLocal(f, inst, operand_lval.new_local, 0);
54765462 }
5477 },
5478 else => unreachable,
5463
5464 return local;
5465 } else {
5466 const name = union_obj.fields.keys()[extra.field_index];
5467 break :field_name if (union_type.hasTag()) .{
5468 .payload_identifier = name,
5469 } else .{
5470 .identifier = name,
5471 };
5472 }
54795473 },
5474 else => unreachable,
54805475 };
54815476
54825477 const local = try f.allocLocal(inst, inst_ty);
src/codegen/llvm.zig+26-31
......@@ -381,12 +381,7 @@ pub const Object = struct {
381381
382382 /// This is an ArrayHashMap as opposed to a HashMap because in `flushModule` we
383383 /// want to iterate over it while adding entries to it.
384 pub const DITypeMap = std.ArrayHashMapUnmanaged(
385 Type,
386 AnnotatedDITypePtr,
387 Type.HashContext32,
388 true,
389 );
384 pub const DITypeMap = std.AutoArrayHashMapUnmanaged(InternPool.Index, AnnotatedDITypePtr);
390385
391386 pub fn create(gpa: Allocator, options: link.Options) !*Object {
392387 const obj = try gpa.create(Object);
......@@ -1437,7 +1432,7 @@ pub const Object = struct {
14371432 const gpa = o.gpa;
14381433 // Be careful not to reference this `gop` variable after any recursive calls
14391434 // to `lowerDebugType`.
1440 const gop = try o.di_type_map.getOrPutContext(gpa, ty, .{ .mod = o.module });
1435 const gop = try o.di_type_map.getOrPut(gpa, ty.toIntern());
14411436 if (gop.found_existing) {
14421437 const annotated = gop.value_ptr.*;
14431438 const di_type = annotated.toDIType();
......@@ -1450,7 +1445,7 @@ pub const Object = struct {
14501445 };
14511446 return o.lowerDebugTypeImpl(entry, resolve, di_type);
14521447 }
1453 errdefer assert(o.di_type_map.orderedRemoveContext(ty, .{ .mod = o.module }));
1448 errdefer assert(o.di_type_map.orderedRemove(ty.toIntern()));
14541449 const entry: Object.DITypeMap.Entry = .{
14551450 .key_ptr = gop.key_ptr,
14561451 .value_ptr = gop.value_ptr,
......@@ -1465,7 +1460,7 @@ pub const Object = struct {
14651460 resolve: DebugResolveStatus,
14661461 opt_fwd_decl: ?*llvm.DIType,
14671462 ) Allocator.Error!*llvm.DIType {
1468 const ty = gop.key_ptr.*;
1463 const ty = gop.key_ptr.toType();
14691464 const gpa = o.gpa;
14701465 const target = o.target;
14711466 const dib = o.di_builder.?;
......@@ -1498,7 +1493,7 @@ pub const Object = struct {
14981493 const enum_di_ty = try o.makeEmptyNamespaceDIType(owner_decl_index);
14991494 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
15001495 // means we can't use `gop` anymore.
1501 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .mod = o.module });
1496 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(enum_di_ty));
15021497 return enum_di_ty;
15031498 }
15041499
......@@ -1558,7 +1553,7 @@ pub const Object = struct {
15581553 "",
15591554 );
15601555 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1561 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(enum_di_ty), .{ .mod = o.module });
1556 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(enum_di_ty));
15621557 return enum_di_ty;
15631558 },
15641559 .Float => {
......@@ -1577,7 +1572,7 @@ pub const Object = struct {
15771572 },
15781573 .Pointer => {
15791574 // Normalize everything that the debug info does not represent.
1580 const ptr_info = ty.ptrInfoIp(mod.intern_pool);
1575 const ptr_info = Type.ptrInfoIp(mod.intern_pool, ty.toIntern());
15811576
15821577 if (ptr_info.sentinel != .none or
15831578 ptr_info.address_space != .generic or
......@@ -1603,7 +1598,7 @@ pub const Object = struct {
16031598 });
16041599 const ptr_di_ty = try o.lowerDebugType(bland_ptr_ty, resolve);
16051600 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1606 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module });
1601 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.init(ptr_di_ty, resolve));
16071602 return ptr_di_ty;
16081603 }
16091604
......@@ -1682,7 +1677,7 @@ pub const Object = struct {
16821677 );
16831678 dib.replaceTemporary(fwd_decl, full_di_ty);
16841679 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1685 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1680 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
16861681 return full_di_ty;
16871682 }
16881683
......@@ -1696,7 +1691,7 @@ pub const Object = struct {
16961691 name,
16971692 );
16981693 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1699 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(ptr_di_ty), .{ .mod = o.module });
1694 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(ptr_di_ty));
17001695 return ptr_di_ty;
17011696 },
17021697 .Opaque => {
......@@ -1718,7 +1713,7 @@ pub const Object = struct {
17181713 );
17191714 // The recursive call to `lowerDebugType` va `namespaceToDebugScope`
17201715 // means we can't use `gop` anymore.
1721 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(opaque_di_ty), .{ .mod = o.module });
1716 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(opaque_di_ty));
17221717 return opaque_di_ty;
17231718 },
17241719 .Array => {
......@@ -1729,7 +1724,7 @@ pub const Object = struct {
17291724 @intCast(c_int, ty.arrayLen(mod)),
17301725 );
17311726 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1732 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .mod = o.module });
1727 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(array_di_ty));
17331728 return array_di_ty;
17341729 },
17351730 .Vector => {
......@@ -1761,7 +1756,7 @@ pub const Object = struct {
17611756 ty.vectorLen(mod),
17621757 );
17631758 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1764 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .mod = o.module });
1759 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(vector_di_ty));
17651760 return vector_di_ty;
17661761 },
17671762 .Optional => {
......@@ -1777,7 +1772,7 @@ pub const Object = struct {
17771772 if (ty.optionalReprIsPayload(mod)) {
17781773 const ptr_di_ty = try o.lowerDebugType(child_ty, resolve);
17791774 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1780 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.init(ptr_di_ty, resolve), .{ .mod = o.module });
1775 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.init(ptr_di_ty, resolve));
17811776 return ptr_di_ty;
17821777 }
17831778
......@@ -1850,7 +1845,7 @@ pub const Object = struct {
18501845 );
18511846 dib.replaceTemporary(fwd_decl, full_di_ty);
18521847 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1853 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1848 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
18541849 return full_di_ty;
18551850 },
18561851 .ErrorUnion => {
......@@ -1858,7 +1853,7 @@ pub const Object = struct {
18581853 if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) {
18591854 const err_set_di_ty = try o.lowerDebugType(Type.anyerror, .full);
18601855 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1861 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(err_set_di_ty), .{ .mod = o.module });
1856 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(err_set_di_ty));
18621857 return err_set_di_ty;
18631858 }
18641859 const name = try ty.nameAlloc(gpa, o.module);
......@@ -1941,7 +1936,7 @@ pub const Object = struct {
19411936 );
19421937 dib.replaceTemporary(fwd_decl, full_di_ty);
19431938 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
1944 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
1939 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
19451940 return full_di_ty;
19461941 },
19471942 .ErrorSet => {
......@@ -2038,7 +2033,7 @@ pub const Object = struct {
20382033 );
20392034 dib.replaceTemporary(fwd_decl, full_di_ty);
20402035 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2041 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
2036 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
20422037 return full_di_ty;
20432038 },
20442039 .struct_type => |struct_type| s: {
......@@ -2057,7 +2052,7 @@ pub const Object = struct {
20572052 dib.replaceTemporary(fwd_decl, struct_di_ty);
20582053 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
20592054 // means we can't use `gop` anymore.
2060 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .mod = o.module });
2055 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(struct_di_ty));
20612056 return struct_di_ty;
20622057 }
20632058 },
......@@ -2070,7 +2065,7 @@ pub const Object = struct {
20702065 dib.replaceTemporary(fwd_decl, struct_di_ty);
20712066 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
20722067 // means we can't use `gop` anymore.
2073 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(struct_di_ty), .{ .mod = o.module });
2068 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(struct_di_ty));
20742069 return struct_di_ty;
20752070 }
20762071
......@@ -2126,7 +2121,7 @@ pub const Object = struct {
21262121 );
21272122 dib.replaceTemporary(fwd_decl, full_di_ty);
21282123 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2129 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
2124 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
21302125 return full_di_ty;
21312126 },
21322127 .Union => {
......@@ -2155,7 +2150,7 @@ pub const Object = struct {
21552150 dib.replaceTemporary(fwd_decl, union_di_ty);
21562151 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
21572152 // means we can't use `gop` anymore.
2158 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .mod = o.module });
2153 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(union_di_ty));
21592154 return union_di_ty;
21602155 }
21612156
......@@ -2182,7 +2177,7 @@ pub const Object = struct {
21822177 dib.replaceTemporary(fwd_decl, full_di_ty);
21832178 // The recursive call to `lowerDebugType` via `makeEmptyNamespaceDIType`
21842179 // means we can't use `gop` anymore.
2185 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
2180 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
21862181 return full_di_ty;
21872182 }
21882183
......@@ -2241,7 +2236,7 @@ pub const Object = struct {
22412236 if (layout.tag_size == 0) {
22422237 dib.replaceTemporary(fwd_decl, union_di_ty);
22432238 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2244 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(union_di_ty), .{ .mod = o.module });
2239 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(union_di_ty));
22452240 return union_di_ty;
22462241 }
22472242
......@@ -2302,7 +2297,7 @@ pub const Object = struct {
23022297 );
23032298 dib.replaceTemporary(fwd_decl, full_di_ty);
23042299 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2305 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(full_di_ty), .{ .mod = o.module });
2300 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(full_di_ty));
23062301 return full_di_ty;
23072302 },
23082303 .Fn => {
......@@ -2349,7 +2344,7 @@ pub const Object = struct {
23492344 0,
23502345 );
23512346 // The recursive call to `lowerDebugType` means we can't use `gop` anymore.
2352 try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(fn_di_ty), .{ .mod = o.module });
2347 try o.di_type_map.put(gpa, ty.toIntern(), AnnotatedDITypePtr.initFull(fn_di_ty));
23532348 return fn_di_ty;
23542349 },
23552350 .ComptimeInt => unreachable,
src/link/Dwarf.zig+4-15
......@@ -87,12 +87,7 @@ pub const DeclState = struct {
8787 dbg_info: std.ArrayList(u8),
8888 abbrev_type_arena: std.heap.ArenaAllocator,
8989 abbrev_table: std.ArrayListUnmanaged(AbbrevEntry) = .{},
90 abbrev_resolver: std.HashMapUnmanaged(
91 Type,
92 u32,
93 Type.HashContext64,
94 std.hash_map.default_max_load_percentage,
95 ) = .{},
90 abbrev_resolver: std.AutoHashMapUnmanaged(InternPool.Index, u32) = .{},
9691 abbrev_relocs: std.ArrayListUnmanaged(AbbrevRelocation) = .{},
9792 exprloc_relocs: std.ArrayListUnmanaged(ExprlocRelocation) = .{},
9893
......@@ -142,9 +137,7 @@ pub const DeclState = struct {
142137 /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
143138 /// which we use as our target of the relocation.
144139 fn addTypeRelocGlobal(self: *DeclState, atom_index: Atom.Index, ty: Type, offset: u32) !void {
145 const resolv = self.abbrev_resolver.getContext(ty, .{
146 .mod = self.mod,
147 }) orelse blk: {
140 const resolv = self.abbrev_resolver.get(ty.toIntern()) orelse blk: {
148141 const sym_index = @intCast(u32, self.abbrev_table.items.len);
149142 try self.abbrev_table.append(self.gpa, .{
150143 .atom_index = atom_index,
......@@ -152,12 +145,8 @@ pub const DeclState = struct {
152145 .offset = undefined,
153146 });
154147 log.debug("%{d}: {}", .{ sym_index, ty.fmt(self.mod) });
155 try self.abbrev_resolver.putNoClobberContext(self.gpa, ty, sym_index, .{
156 .mod = self.mod,
157 });
158 break :blk self.abbrev_resolver.getContext(ty, .{
159 .mod = self.mod,
160 }).?;
148 try self.abbrev_resolver.putNoClobber(self.gpa, ty.toIntern(), sym_index);
149 break :blk sym_index;
161150 };
162151 log.debug("{x}: %{d} + 0", .{ offset, resolv });
163152 try self.abbrev_relocs.append(self.gpa, .{
src/print_air.zig+1-7
......@@ -366,13 +366,7 @@ const Writer = struct {
366366 }
367367
368368 fn writeType(w: *Writer, s: anytype, ty: Type) !void {
369 switch (ty.ip_index) {
370 .none => switch (ty.tag()) {
371 .inferred_alloc_const => try s.writeAll("(inferred_alloc_const)"),
372 .inferred_alloc_mut => try s.writeAll("(inferred_alloc_mut)"),
373 },
374 else => try ty.print(s, w.module),
375 }
369 return ty.print(s, w.module);
376370 }
377371
378372 fn writeTy(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/type.zig+398-658
......@@ -11,115 +11,99 @@ const TypedValue = @import("TypedValue.zig");
1111const Sema = @import("Sema.zig");
1212const InternPool = @import("InternPool.zig");
1313
14const file_struct = @This();
15
14/// Both types and values are canonically represented by a single 32-bit integer
15/// which is an index into an `InternPool` data structure.
16/// This struct abstracts around this storage by providing methods only
17/// applicable to types rather than values in general.
1618pub const Type = struct {
17 /// We are migrating towards using this for every Type object. However, many
18 /// types are still represented the legacy way. This is indicated by using
19 /// InternPool.Index.none.
2019 ip_index: InternPool.Index,
2120
22 /// This is the raw data, with no bookkeeping, no memory awareness, no de-duplication.
23 /// This union takes advantage of the fact that the first page of memory
24 /// is unmapped, giving us 4096 possible enum tags that have no payload.
25 legacy: extern union {
26 /// If the tag value is less than Tag.no_payload_count, then no pointer
27 /// dereference is needed.
28 tag_if_small_enough: Tag,
29 ptr_otherwise: *Payload,
30 },
31
3221 pub fn zigTypeTag(ty: Type, mod: *const Module) std.builtin.TypeId {
3322 return ty.zigTypeTagOrPoison(mod) catch unreachable;
3423 }
3524
3625 pub fn zigTypeTagOrPoison(ty: Type, mod: *const Module) error{GenericPoison}!std.builtin.TypeId {
37 switch (ty.ip_index) {
38 .none => switch (ty.tag()) {
39 .inferred_alloc_const,
40 .inferred_alloc_mut,
41 => return .Pointer,
42 },
43 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
44 .int_type => .Int,
45 .ptr_type => .Pointer,
46 .array_type => .Array,
47 .vector_type => .Vector,
48 .opt_type => .Optional,
49 .error_union_type => .ErrorUnion,
50 .error_set_type, .inferred_error_set_type => .ErrorSet,
51 .struct_type, .anon_struct_type => .Struct,
52 .union_type => .Union,
53 .opaque_type => .Opaque,
54 .enum_type => .Enum,
55 .func_type => .Fn,
56 .anyframe_type => .AnyFrame,
57 .simple_type => |s| switch (s) {
58 .f16,
59 .f32,
60 .f64,
61 .f80,
62 .f128,
63 .c_longdouble,
64 => .Float,
26 return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
27 .int_type => .Int,
28 .ptr_type => .Pointer,
29 .array_type => .Array,
30 .vector_type => .Vector,
31 .opt_type => .Optional,
32 .error_union_type => .ErrorUnion,
33 .error_set_type, .inferred_error_set_type => .ErrorSet,
34 .struct_type, .anon_struct_type => .Struct,
35 .union_type => .Union,
36 .opaque_type => .Opaque,
37 .enum_type => .Enum,
38 .func_type => .Fn,
39 .anyframe_type => .AnyFrame,
40 .simple_type => |s| switch (s) {
41 .f16,
42 .f32,
43 .f64,
44 .f80,
45 .f128,
46 .c_longdouble,
47 => .Float,
6548
66 .usize,
67 .isize,
68 .c_char,
69 .c_short,
70 .c_ushort,
71 .c_int,
72 .c_uint,
73 .c_long,
74 .c_ulong,
75 .c_longlong,
76 .c_ulonglong,
77 => .Int,
78
79 .anyopaque => .Opaque,
80 .bool => .Bool,
81 .void => .Void,
82 .type => .Type,
83 .anyerror => .ErrorSet,
84 .comptime_int => .ComptimeInt,
85 .comptime_float => .ComptimeFloat,
86 .noreturn => .NoReturn,
87 .null => .Null,
88 .undefined => .Undefined,
89 .enum_literal => .EnumLiteral,
49 .usize,
50 .isize,
51 .c_char,
52 .c_short,
53 .c_ushort,
54 .c_int,
55 .c_uint,
56 .c_long,
57 .c_ulong,
58 .c_longlong,
59 .c_ulonglong,
60 => .Int,
61
62 .anyopaque => .Opaque,
63 .bool => .Bool,
64 .void => .Void,
65 .type => .Type,
66 .anyerror => .ErrorSet,
67 .comptime_int => .ComptimeInt,
68 .comptime_float => .ComptimeFloat,
69 .noreturn => .NoReturn,
70 .null => .Null,
71 .undefined => .Undefined,
72 .enum_literal => .EnumLiteral,
9073
91 .atomic_order,
92 .atomic_rmw_op,
93 .calling_convention,
94 .address_space,
95 .float_mode,
96 .reduce_op,
97 .call_modifier,
98 => .Enum,
74 .atomic_order,
75 .atomic_rmw_op,
76 .calling_convention,
77 .address_space,
78 .float_mode,
79 .reduce_op,
80 .call_modifier,
81 => .Enum,
9982
100 .prefetch_options,
101 .export_options,
102 .extern_options,
103 => .Struct,
83 .prefetch_options,
84 .export_options,
85 .extern_options,
86 => .Struct,
10487
105 .type_info => .Union,
88 .type_info => .Union,
10689
107 .generic_poison => return error.GenericPoison,
108 },
90 .generic_poison => return error.GenericPoison,
10991
110 // values, not types
111 .undef => unreachable,
112 .un => unreachable,
113 .extern_func => unreachable,
114 .int => unreachable,
115 .float => unreachable,
116 .ptr => unreachable,
117 .opt => unreachable,
118 .enum_tag => unreachable,
119 .simple_value => unreachable,
120 .aggregate => unreachable,
92 .inferred_alloc_const, .inferred_alloc_mut => return .Pointer,
12193 },
122 }
94
95 // values, not types
96 .undef => unreachable,
97 .un => unreachable,
98 .extern_func => unreachable,
99 .int => unreachable,
100 .float => unreachable,
101 .ptr => unreachable,
102 .opt => unreachable,
103 .enum_tag => unreachable,
104 .simple_value => unreachable,
105 .aggregate => unreachable,
106 };
123107 }
124108
125109 pub fn baseZigTypeTag(self: Type, mod: *Module) std.builtin.TypeId {
......@@ -171,68 +155,6 @@ pub const Type = struct {
171155 };
172156 }
173157
174 pub fn initTag(comptime small_tag: Tag) Type {
175 comptime assert(@enumToInt(small_tag) < Tag.no_payload_count);
176 return Type{
177 .ip_index = .none,
178 .legacy = .{ .tag_if_small_enough = small_tag },
179 };
180 }
181
182 pub fn initPayload(payload: *Payload) Type {
183 assert(@enumToInt(payload.tag) >= Tag.no_payload_count);
184 return Type{
185 .ip_index = .none,
186 .legacy = .{ .ptr_otherwise = payload },
187 };
188 }
189
190 pub fn tag(ty: Type) Tag {
191 assert(ty.ip_index == .none);
192 if (@enumToInt(ty.legacy.tag_if_small_enough) < Tag.no_payload_count) {
193 return ty.legacy.tag_if_small_enough;
194 } else {
195 return ty.legacy.ptr_otherwise.tag;
196 }
197 }
198
199 /// Prefer `castTag` to this.
200 pub fn cast(self: Type, comptime T: type) ?*T {
201 if (self.ip_index != .none) {
202 return null;
203 }
204 if (@hasField(T, "base_tag")) {
205 return self.castTag(T.base_tag);
206 }
207 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) {
208 return null;
209 }
210 inline for (@typeInfo(Tag).Enum.fields) |field| {
211 if (field.value < Tag.no_payload_count)
212 continue;
213 const t = @intToEnum(Tag, field.value);
214 if (self.legacy.ptr_otherwise.tag == t) {
215 if (T == t.Type()) {
216 return @fieldParentPtr(T, "base", self.legacy.ptr_otherwise);
217 }
218 return null;
219 }
220 }
221 unreachable;
222 }
223
224 pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() {
225 if (self.ip_index != .none) return null;
226
227 if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count)
228 return null;
229
230 if (self.legacy.ptr_otherwise.tag == t)
231 return @fieldParentPtr(t.Type(), "base", self.legacy.ptr_otherwise);
232
233 return null;
234 }
235
236158 /// If it is a function pointer, returns the function type. Otherwise returns null.
237159 pub fn castPtrToFn(ty: Type, mod: *const Module) ?Type {
238160 if (ty.zigTypeTag(mod) != .Pointer) return null;
......@@ -260,8 +182,8 @@ pub const Type = struct {
260182 };
261183 }
262184
263 pub fn ptrInfoIp(ty: Type, ip: InternPool) InternPool.Key.PtrType {
264 return switch (ip.indexToKey(ty.ip_index)) {
185 pub fn ptrInfoIp(ip: InternPool, ty: InternPool.Index) InternPool.Key.PtrType {
186 return switch (ip.indexToKey(ty)) {
265187 .ptr_type => |p| p,
266188 .opt_type => |child| switch (ip.indexToKey(child)) {
267189 .ptr_type => |p| p,
......@@ -272,135 +194,28 @@ pub const Type = struct {
272194 }
273195
274196 pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data {
275 return Payload.Pointer.Data.fromKey(ptrInfoIp(ty, mod.intern_pool));
276 }
277
278 pub fn eql(a: Type, b: Type, mod: *Module) bool {
279 if (a.ip_index != .none or b.ip_index != .none) {
280 // The InternPool data structure hashes based on Key to make interned objects
281 // unique. An Index can be treated simply as u32 value for the
282 // purpose of Type/Value hashing and equality.
283 return a.ip_index == b.ip_index;
284 }
285 // As a shortcut, if the small tags / addresses match, we're done.
286 if (a.legacy.tag_if_small_enough == b.legacy.tag_if_small_enough) return true;
287
288 switch (a.tag()) {
289 .inferred_alloc_const,
290 .inferred_alloc_mut,
291 => {
292 if (b.zigTypeTag(mod) != .Pointer) return false;
293
294 const info_a = a.ptrInfo(mod);
295 const info_b = b.ptrInfo(mod);
296 if (!info_a.pointee_type.eql(info_b.pointee_type, mod))
297 return false;
298 if (info_a.@"align" != info_b.@"align")
299 return false;
300 if (info_a.@"addrspace" != info_b.@"addrspace")
301 return false;
302 if (info_a.bit_offset != info_b.bit_offset)
303 return false;
304 if (info_a.host_size != info_b.host_size)
305 return false;
306 if (info_a.vector_index != info_b.vector_index)
307 return false;
308 if (info_a.@"allowzero" != info_b.@"allowzero")
309 return false;
310 if (info_a.mutable != info_b.mutable)
311 return false;
312 if (info_a.@"volatile" != info_b.@"volatile")
313 return false;
314 if (info_a.size != info_b.size)
315 return false;
316
317 const sentinel_a = info_a.sentinel;
318 const sentinel_b = info_b.sentinel;
319 if (sentinel_a) |sa| {
320 if (sentinel_b) |sb| {
321 if (!sa.eql(sb, info_a.pointee_type, mod))
322 return false;
323 } else {
324 return false;
325 }
326 } else {
327 if (sentinel_b != null)
328 return false;
329 }
330
331 return true;
332 },
333 }
197 return Payload.Pointer.Data.fromKey(ptrInfoIp(mod.intern_pool, ty.ip_index));
334198 }
335199
336 pub fn hash(self: Type, mod: *Module) u64 {
337 var hasher = std.hash.Wyhash.init(0);
338 self.hashWithHasher(&hasher, mod);
339 return hasher.final();
200 pub fn eql(a: Type, b: Type, mod: *const Module) bool {
201 _ = mod; // TODO: remove this parameter
202 assert(a.ip_index != .none);
203 assert(b.ip_index != .none);
204 // The InternPool data structure hashes based on Key to make interned objects
205 // unique. An Index can be treated simply as u32 value for the
206 // purpose of Type/Value hashing and equality.
207 return a.ip_index == b.ip_index;
340208 }
341209
342 pub fn hashWithHasher(ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
343 if (ty.ip_index != .none) {
344 // The InternPool data structure hashes based on Key to make interned objects
345 // unique. An Index can be treated simply as u32 value for the
346 // purpose of Type/Value hashing and equality.
347 std.hash.autoHash(hasher, ty.ip_index);
348 return;
349 }
350 switch (ty.tag()) {
351 .inferred_alloc_const,
352 .inferred_alloc_mut,
353 => {
354 std.hash.autoHash(hasher, std.builtin.TypeId.Pointer);
355
356 const info = ty.ptrInfo(mod);
357 hashWithHasher(info.pointee_type, hasher, mod);
358 hashSentinel(info.sentinel, info.pointee_type, hasher, mod);
359 std.hash.autoHash(hasher, info.@"align");
360 std.hash.autoHash(hasher, info.@"addrspace");
361 std.hash.autoHash(hasher, info.bit_offset);
362 std.hash.autoHash(hasher, info.host_size);
363 std.hash.autoHash(hasher, info.vector_index);
364 std.hash.autoHash(hasher, info.@"allowzero");
365 std.hash.autoHash(hasher, info.mutable);
366 std.hash.autoHash(hasher, info.@"volatile");
367 std.hash.autoHash(hasher, info.size);
368 },
369 }
370 }
371
372 fn hashSentinel(opt_val: ?Value, ty: Type, hasher: *std.hash.Wyhash, mod: *Module) void {
373 if (opt_val) |s| {
374 std.hash.autoHash(hasher, true);
375 s.hash(ty, hasher, mod);
376 } else {
377 std.hash.autoHash(hasher, false);
378 }
210 pub fn hash(ty: Type, mod: *const Module) u32 {
211 _ = mod; // TODO: remove this parameter
212 assert(ty.ip_index != .none);
213 // The InternPool data structure hashes based on Key to make interned objects
214 // unique. An Index can be treated simply as u32 value for the
215 // purpose of Type/Value hashing and equality.
216 return std.hash.uint32(@enumToInt(ty.ip_index));
379217 }
380218
381 pub const HashContext64 = struct {
382 mod: *Module,
383
384 pub fn hash(self: @This(), t: Type) u64 {
385 return t.hash(self.mod);
386 }
387 pub fn eql(self: @This(), a: Type, b: Type) bool {
388 return a.eql(b, self.mod);
389 }
390 };
391
392 pub const HashContext32 = struct {
393 mod: *Module,
394
395 pub fn hash(self: @This(), t: Type) u32 {
396 return @truncate(u32, t.hash(self.mod));
397 }
398 pub fn eql(self: @This(), a: Type, b: Type, b_index: usize) bool {
399 _ = b_index;
400 return a.eql(b, self.mod);
401 }
402 };
403
404219 pub fn format(ty: Type, comptime unused_fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype) !void {
405220 _ = ty;
406221 _ = unused_fmt_string;
......@@ -460,214 +275,208 @@ pub const Type = struct {
460275
461276 /// Prints a name suitable for `@typeName`.
462277 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
463 switch (ty.ip_index) {
464 .none => switch (ty.tag()) {
465 .inferred_alloc_const => unreachable,
466 .inferred_alloc_mut => unreachable,
278 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
279 .int_type => |int_type| {
280 const sign_char: u8 = switch (int_type.signedness) {
281 .signed => 'i',
282 .unsigned => 'u',
283 };
284 return writer.print("{c}{d}", .{ sign_char, int_type.bits });
467285 },
468 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
469 .int_type => |int_type| {
470 const sign_char: u8 = switch (int_type.signedness) {
471 .signed => 'i',
472 .unsigned => 'u',
473 };
474 return writer.print("{c}{d}", .{ sign_char, int_type.bits });
475 },
476 .ptr_type => {
477 const info = ty.ptrInfo(mod);
478
479 if (info.sentinel) |s| switch (info.size) {
480 .One, .C => unreachable,
481 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),
482 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),
483 } else switch (info.size) {
484 .One => try writer.writeAll("*"),
485 .Many => try writer.writeAll("[*]"),
486 .C => try writer.writeAll("[*c]"),
487 .Slice => try writer.writeAll("[]"),
488 }
489 if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {
490 if (info.@"align" != 0) {
491 try writer.print("align({d}", .{info.@"align"});
492 } else {
493 const alignment = info.pointee_type.abiAlignment(mod);
494 try writer.print("align({d}", .{alignment});
495 }
286 .ptr_type => {
287 const info = ty.ptrInfo(mod);
496288
497 if (info.bit_offset != 0 or info.host_size != 0) {
498 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
499 }
500 if (info.vector_index == .runtime) {
501 try writer.writeAll(":?");
502 } else if (info.vector_index != .none) {
503 try writer.print(":{d}", .{@enumToInt(info.vector_index)});
504 }
505 try writer.writeAll(") ");
506 }
507 if (info.@"addrspace" != .generic) {
508 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
289 if (info.sentinel) |s| switch (info.size) {
290 .One, .C => unreachable,
291 .Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),
292 .Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),
293 } else switch (info.size) {
294 .One => try writer.writeAll("*"),
295 .Many => try writer.writeAll("[*]"),
296 .C => try writer.writeAll("[*c]"),
297 .Slice => try writer.writeAll("[]"),
298 }
299 if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {
300 if (info.@"align" != 0) {
301 try writer.print("align({d}", .{info.@"align"});
302 } else {
303 const alignment = info.pointee_type.abiAlignment(mod);
304 try writer.print("align({d}", .{alignment});
509305 }
510 if (!info.mutable) try writer.writeAll("const ");
511 if (info.@"volatile") try writer.writeAll("volatile ");
512 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
513306
514 try print(info.pointee_type, writer, mod);
515 return;
516 },
517 .array_type => |array_type| {
518 if (array_type.sentinel == .none) {
519 try writer.print("[{d}]", .{array_type.len});
520 try print(array_type.child.toType(), writer, mod);
521 } else {
522 try writer.print("[{d}:{}]", .{
523 array_type.len,
524 array_type.sentinel.toValue().fmtValue(array_type.child.toType(), mod),
525 });
526 try print(array_type.child.toType(), writer, mod);
307 if (info.bit_offset != 0 or info.host_size != 0) {
308 try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
527309 }
528 return;
529 },
530 .vector_type => |vector_type| {
531 try writer.print("@Vector({d}, ", .{vector_type.len});
532 try print(vector_type.child.toType(), writer, mod);
533 try writer.writeAll(")");
534 return;
535 },
536 .opt_type => |child| {
537 try writer.writeByte('?');
538 return print(child.toType(), writer, mod);
539 },
540 .error_union_type => |error_union_type| {
541 try print(error_union_type.error_set_type.toType(), writer, mod);
542 try writer.writeByte('!');
543 try print(error_union_type.payload_type.toType(), writer, mod);
544 return;
545 },
546 .inferred_error_set_type => |index| {
547 const ies = mod.inferredErrorSetPtr(index);
548 const func = ies.func;
310 if (info.vector_index == .runtime) {
311 try writer.writeAll(":?");
312 } else if (info.vector_index != .none) {
313 try writer.print(":{d}", .{@enumToInt(info.vector_index)});
314 }
315 try writer.writeAll(") ");
316 }
317 if (info.@"addrspace" != .generic) {
318 try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
319 }
320 if (!info.mutable) try writer.writeAll("const ");
321 if (info.@"volatile") try writer.writeAll("volatile ");
322 if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
549323
550 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
551 const owner_decl = mod.declPtr(func.owner_decl);
552 try owner_decl.renderFullyQualifiedName(mod, writer);
553 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
554 },
555 .error_set_type => |error_set_type| {
556 const names = error_set_type.names;
557 try writer.writeAll("error{");
558 for (names, 0..) |name, i| {
559 if (i != 0) try writer.writeByte(',');
560 try writer.writeAll(mod.intern_pool.stringToSlice(name));
324 try print(info.pointee_type, writer, mod);
325 return;
326 },
327 .array_type => |array_type| {
328 if (array_type.sentinel == .none) {
329 try writer.print("[{d}]", .{array_type.len});
330 try print(array_type.child.toType(), writer, mod);
331 } else {
332 try writer.print("[{d}:{}]", .{
333 array_type.len,
334 array_type.sentinel.toValue().fmtValue(array_type.child.toType(), mod),
335 });
336 try print(array_type.child.toType(), writer, mod);
337 }
338 return;
339 },
340 .vector_type => |vector_type| {
341 try writer.print("@Vector({d}, ", .{vector_type.len});
342 try print(vector_type.child.toType(), writer, mod);
343 try writer.writeAll(")");
344 return;
345 },
346 .opt_type => |child| {
347 try writer.writeByte('?');
348 return print(child.toType(), writer, mod);
349 },
350 .error_union_type => |error_union_type| {
351 try print(error_union_type.error_set_type.toType(), writer, mod);
352 try writer.writeByte('!');
353 try print(error_union_type.payload_type.toType(), writer, mod);
354 return;
355 },
356 .inferred_error_set_type => |index| {
357 const ies = mod.inferredErrorSetPtr(index);
358 const func = ies.func;
359
360 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
361 const owner_decl = mod.declPtr(func.owner_decl);
362 try owner_decl.renderFullyQualifiedName(mod, writer);
363 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
364 },
365 .error_set_type => |error_set_type| {
366 const names = error_set_type.names;
367 try writer.writeAll("error{");
368 for (names, 0..) |name, i| {
369 if (i != 0) try writer.writeByte(',');
370 try writer.writeAll(mod.intern_pool.stringToSlice(name));
371 }
372 try writer.writeAll("}");
373 },
374 .simple_type => |s| return writer.writeAll(@tagName(s)),
375 .struct_type => |struct_type| {
376 if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
377 const decl = mod.declPtr(struct_obj.owner_decl);
378 try decl.renderFullyQualifiedName(mod, writer);
379 } else if (struct_type.namespace.unwrap()) |namespace_index| {
380 const namespace = mod.namespacePtr(namespace_index);
381 try namespace.renderFullyQualifiedName(mod, "", writer);
382 } else {
383 try writer.writeAll("@TypeOf(.{})");
384 }
385 },
386 .anon_struct_type => |anon_struct| {
387 try writer.writeAll("struct{");
388 for (anon_struct.types, anon_struct.values, 0..) |field_ty, val, i| {
389 if (i != 0) try writer.writeAll(", ");
390 if (val != .none) {
391 try writer.writeAll("comptime ");
561392 }
562 try writer.writeAll("}");
563 },
564 .simple_type => |s| return writer.writeAll(@tagName(s)),
565 .struct_type => |struct_type| {
566 if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
567 const decl = mod.declPtr(struct_obj.owner_decl);
568 try decl.renderFullyQualifiedName(mod, writer);
569 } else if (struct_type.namespace.unwrap()) |namespace_index| {
570 const namespace = mod.namespacePtr(namespace_index);
571 try namespace.renderFullyQualifiedName(mod, "", writer);
572 } else {
573 try writer.writeAll("@TypeOf(.{})");
393 if (anon_struct.names.len != 0) {
394 const name = mod.intern_pool.stringToSlice(anon_struct.names[i]);
395 try writer.writeAll(name);
396 try writer.writeAll(": ");
574397 }
575 },
576 .anon_struct_type => |anon_struct| {
577 try writer.writeAll("struct{");
578 for (anon_struct.types, anon_struct.values, 0..) |field_ty, val, i| {
579 if (i != 0) try writer.writeAll(", ");
580 if (val != .none) {
581 try writer.writeAll("comptime ");
582 }
583 if (anon_struct.names.len != 0) {
584 const name = mod.intern_pool.stringToSlice(anon_struct.names[i]);
585 try writer.writeAll(name);
586 try writer.writeAll(": ");
587 }
588398
589 try print(field_ty.toType(), writer, mod);
399 try print(field_ty.toType(), writer, mod);
590400
591 if (val != .none) {
592 try writer.print(" = {}", .{val.toValue().fmtValue(field_ty.toType(), mod)});
593 }
401 if (val != .none) {
402 try writer.print(" = {}", .{val.toValue().fmtValue(field_ty.toType(), mod)});
594403 }
595 try writer.writeAll("}");
596 },
404 }
405 try writer.writeAll("}");
406 },
597407
598 .union_type => |union_type| {
599 const union_obj = mod.unionPtr(union_type.index);
600 const decl = mod.declPtr(union_obj.owner_decl);
601 try decl.renderFullyQualifiedName(mod, writer);
602 },
603 .opaque_type => |opaque_type| {
604 const decl = mod.declPtr(opaque_type.decl);
605 try decl.renderFullyQualifiedName(mod, writer);
606 },
607 .enum_type => |enum_type| {
608 const decl = mod.declPtr(enum_type.decl);
609 try decl.renderFullyQualifiedName(mod, writer);
610 },
611 .func_type => |fn_info| {
612 if (fn_info.is_noinline) {
613 try writer.writeAll("noinline ");
614 }
615 try writer.writeAll("fn(");
616 for (fn_info.param_types, 0..) |param_ty, i| {
617 if (i != 0) try writer.writeAll(", ");
618 if (std.math.cast(u5, i)) |index| {
619 if (fn_info.paramIsComptime(index)) {
620 try writer.writeAll("comptime ");
621 }
622 if (fn_info.paramIsNoalias(index)) {
623 try writer.writeAll("noalias ");
624 }
625 }
626 if (param_ty == .generic_poison_type) {
627 try writer.writeAll("anytype");
628 } else {
629 try print(param_ty.toType(), writer, mod);
408 .union_type => |union_type| {
409 const union_obj = mod.unionPtr(union_type.index);
410 const decl = mod.declPtr(union_obj.owner_decl);
411 try decl.renderFullyQualifiedName(mod, writer);
412 },
413 .opaque_type => |opaque_type| {
414 const decl = mod.declPtr(opaque_type.decl);
415 try decl.renderFullyQualifiedName(mod, writer);
416 },
417 .enum_type => |enum_type| {
418 const decl = mod.declPtr(enum_type.decl);
419 try decl.renderFullyQualifiedName(mod, writer);
420 },
421 .func_type => |fn_info| {
422 if (fn_info.is_noinline) {
423 try writer.writeAll("noinline ");
424 }
425 try writer.writeAll("fn(");
426 for (fn_info.param_types, 0..) |param_ty, i| {
427 if (i != 0) try writer.writeAll(", ");
428 if (std.math.cast(u5, i)) |index| {
429 if (fn_info.paramIsComptime(index)) {
430 try writer.writeAll("comptime ");
630431 }
631 }
632 if (fn_info.is_var_args) {
633 if (fn_info.param_types.len != 0) {
634 try writer.writeAll(", ");
432 if (fn_info.paramIsNoalias(index)) {
433 try writer.writeAll("noalias ");
635434 }
636 try writer.writeAll("...");
637 }
638 try writer.writeAll(") ");
639 if (fn_info.alignment.toByteUnitsOptional()) |a| {
640 try writer.print("align({d}) ", .{a});
641 }
642 if (fn_info.cc != .Unspecified) {
643 try writer.writeAll("callconv(.");
644 try writer.writeAll(@tagName(fn_info.cc));
645 try writer.writeAll(") ");
646435 }
647 if (fn_info.return_type == .generic_poison_type) {
436 if (param_ty == .generic_poison_type) {
648437 try writer.writeAll("anytype");
649438 } else {
650 try print(fn_info.return_type.toType(), writer, mod);
439 try print(param_ty.toType(), writer, mod);
651440 }
652 },
653 .anyframe_type => |child| {
654 if (child == .none) return writer.writeAll("anyframe");
655 try writer.writeAll("anyframe->");
656 return print(child.toType(), writer, mod);
657 },
658
659 // values, not types
660 .undef => unreachable,
661 .un => unreachable,
662 .simple_value => unreachable,
663 .extern_func => unreachable,
664 .int => unreachable,
665 .float => unreachable,
666 .ptr => unreachable,
667 .opt => unreachable,
668 .enum_tag => unreachable,
669 .aggregate => unreachable,
441 }
442 if (fn_info.is_var_args) {
443 if (fn_info.param_types.len != 0) {
444 try writer.writeAll(", ");
445 }
446 try writer.writeAll("...");
447 }
448 try writer.writeAll(") ");
449 if (fn_info.alignment.toByteUnitsOptional()) |a| {
450 try writer.print("align({d}) ", .{a});
451 }
452 if (fn_info.cc != .Unspecified) {
453 try writer.writeAll("callconv(.");
454 try writer.writeAll(@tagName(fn_info.cc));
455 try writer.writeAll(") ");
456 }
457 if (fn_info.return_type == .generic_poison_type) {
458 try writer.writeAll("anytype");
459 } else {
460 try print(fn_info.return_type.toType(), writer, mod);
461 }
462 },
463 .anyframe_type => |child| {
464 if (child == .none) return writer.writeAll("anyframe");
465 try writer.writeAll("anyframe->");
466 return print(child.toType(), writer, mod);
670467 },
468
469 // values, not types
470 .undef => unreachable,
471 .un => unreachable,
472 .simple_value => unreachable,
473 .extern_func => unreachable,
474 .int => unreachable,
475 .float => unreachable,
476 .ptr => unreachable,
477 .opt => unreachable,
478 .enum_tag => unreachable,
479 .aggregate => unreachable,
671480 }
672481 }
673482
......@@ -699,15 +508,10 @@ pub const Type = struct {
699508 ignore_comptime_only: bool,
700509 strat: AbiAlignmentAdvancedStrat,
701510 ) RuntimeBitsError!bool {
702 switch (ty.ip_index) {
511 return switch (ty.ip_index) {
703512 // False because it is a comptime-only type.
704 .empty_struct_type => return false,
705
706 .none => switch (ty.tag()) {
707 .inferred_alloc_const => unreachable,
708 .inferred_alloc_mut => unreachable,
709 },
710 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
513 .empty_struct_type => false,
514 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
711515 .int_type => |int_type| int_type.bits != 0,
712516 .ptr_type => |ptr_type| {
713517 // Pointers to zero-bit types still have a runtime address; however, pointers
......@@ -802,6 +606,8 @@ pub const Type = struct {
802606 => false,
803607
804608 .generic_poison => unreachable,
609 .inferred_alloc_const => unreachable,
610 .inferred_alloc_mut => unreachable,
805611 },
806612 .struct_type => |struct_type| {
807613 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
......@@ -880,7 +686,7 @@ pub const Type = struct {
880686 .enum_tag => unreachable,
881687 .aggregate => unreachable,
882688 },
883 }
689 };
884690 }
885691
886692 /// true if and only if the type has a well-defined memory layout
......@@ -950,6 +756,9 @@ pub const Type = struct {
950756 .type_info,
951757 .generic_poison,
952758 => false,
759
760 .inferred_alloc_const => unreachable,
761 .inferred_alloc_mut => unreachable,
953762 },
954763 .struct_type => |struct_type| {
955764 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse {
......@@ -1167,10 +976,7 @@ pub const Type = struct {
1167976 .f80 => switch (target.c_type_bit_size(.longdouble)) {
1168977 80 => return AbiAlignmentAdvanced{ .scalar = target.c_type_alignment(.longdouble) },
1169978 else => {
1170 const u80_ty: Type = .{
1171 .ip_index = .u80_type,
1172 .legacy = undefined,
1173 };
979 const u80_ty: Type = .{ .ip_index = .u80_type };
1174980 return AbiAlignmentAdvanced{ .scalar = abiAlignment(u80_ty, mod) };
1175981 },
1176982 },
......@@ -1194,6 +1000,8 @@ pub const Type = struct {
11941000
11951001 .noreturn => unreachable,
11961002 .generic_poison => unreachable,
1003 .inferred_alloc_const => unreachable,
1004 .inferred_alloc_mut => unreachable,
11971005 },
11981006 .struct_type => |struct_type| {
11991007 const struct_obj = mod.structPtrUnwrap(struct_type.index) orelse
......@@ -1562,10 +1370,7 @@ pub const Type = struct {
15621370 .f80 => switch (target.c_type_bit_size(.longdouble)) {
15631371 80 => return AbiSizeAdvanced{ .scalar = target.c_type_byte_size(.longdouble) },
15641372 else => {
1565 const u80_ty: Type = .{
1566 .ip_index = .u80_type,
1567 .legacy = undefined,
1568 };
1373 const u80_ty: Type = .{ .ip_index = .u80_type };
15691374 return AbiSizeAdvanced{ .scalar = abiSize(u80_ty, mod) };
15701375 },
15711376 },
......@@ -1605,6 +1410,8 @@ pub const Type = struct {
16051410 .type_info => unreachable,
16061411 .noreturn => unreachable,
16071412 .generic_poison => unreachable,
1413 .inferred_alloc_const => unreachable,
1414 .inferred_alloc_mut => unreachable,
16081415 },
16091416 .struct_type => |struct_type| switch (ty.containerLayout(mod)) {
16101417 .Packed => {
......@@ -1835,6 +1642,8 @@ pub const Type = struct {
18351642 .undefined => unreachable,
18361643 .enum_literal => unreachable,
18371644 .generic_poison => unreachable,
1645 .inferred_alloc_const => unreachable,
1646 .inferred_alloc_mut => unreachable,
18381647
18391648 .atomic_order => unreachable, // missing call to resolveTypeFields
18401649 .atomic_rmw_op => unreachable, // missing call to resolveTypeFields
......@@ -1927,17 +1736,13 @@ pub const Type = struct {
19271736 }
19281737
19291738 pub fn isSinglePointer(ty: Type, mod: *const Module) bool {
1930 switch (ty.ip_index) {
1931 .none => return switch (ty.tag()) {
1932 .inferred_alloc_const,
1933 .inferred_alloc_mut,
1934 => true,
1935 },
1936 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
1739 return switch (ty.ip_index) {
1740 .inferred_alloc_const_type, .inferred_alloc_mut_type => true,
1741 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
19371742 .ptr_type => |ptr_info| ptr_info.size == .One,
19381743 else => false,
19391744 },
1940 }
1745 };
19411746 }
19421747
19431748 /// Asserts `ty` is a pointer.
......@@ -1948,11 +1753,7 @@ pub const Type = struct {
19481753 /// Returns `null` if `ty` is not a pointer.
19491754 pub fn ptrSizeOrNull(ty: Type, mod: *const Module) ?std.builtin.Type.Pointer.Size {
19501755 return switch (ty.ip_index) {
1951 .none => switch (ty.tag()) {
1952 .inferred_alloc_const,
1953 .inferred_alloc_mut,
1954 => .One,
1955 },
1756 .inferred_alloc_const_type, .inferred_alloc_mut_type => .One,
19561757 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
19571758 .ptr_type => |ptr_info| ptr_info.size,
19581759 else => null,
......@@ -2625,10 +2426,6 @@ pub const Type = struct {
26252426 while (true) switch (ty.ip_index) {
26262427 .empty_struct_type => return Value.empty_struct,
26272428
2628 .none => switch (ty.tag()) {
2629 .inferred_alloc_const => unreachable,
2630 .inferred_alloc_mut => unreachable,
2631 },
26322429 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
26332430 .int_type => |int_type| {
26342431 if (int_type.bits == 0) {
......@@ -2710,6 +2507,8 @@ pub const Type = struct {
27102507 .undefined => return Value.undef,
27112508
27122509 .generic_poison => unreachable,
2510 .inferred_alloc_const => unreachable,
2511 .inferred_alloc_mut => unreachable,
27132512 },
27142513 .struct_type => |struct_type| {
27152514 if (mod.structPtrUnwrap(struct_type.index)) |s| {
......@@ -2888,6 +2687,9 @@ pub const Type = struct {
28882687 .enum_literal,
28892688 .type_info,
28902689 => true,
2690
2691 .inferred_alloc_const => unreachable,
2692 .inferred_alloc_mut => unreachable,
28912693 },
28922694 .struct_type => |struct_type| {
28932695 // A struct with no fields is not comptime-only.
......@@ -3343,61 +3145,56 @@ pub const Type = struct {
33433145
33443146 /// Supports structs and unions.
33453147 pub fn structFieldOffset(ty: Type, index: usize, mod: *Module) u64 {
3346 switch (ty.ip_index) {
3347 .none => switch (ty.tag()) {
3348 else => unreachable,
3349 },
3350 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3351 .struct_type => |struct_type| {
3352 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3353 assert(struct_obj.haveLayout());
3354 assert(struct_obj.layout != .Packed);
3355 var it = ty.iterateStructOffsets(mod);
3356 while (it.next()) |field_offset| {
3357 if (index == field_offset.field)
3358 return field_offset.offset;
3359 }
3360
3361 return std.mem.alignForwardGeneric(u64, it.offset, @max(it.big_align, 1));
3362 },
3148 switch (mod.intern_pool.indexToKey(ty.ip_index)) {
3149 .struct_type => |struct_type| {
3150 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
3151 assert(struct_obj.haveLayout());
3152 assert(struct_obj.layout != .Packed);
3153 var it = ty.iterateStructOffsets(mod);
3154 while (it.next()) |field_offset| {
3155 if (index == field_offset.field)
3156 return field_offset.offset;
3157 }
33633158
3364 .anon_struct_type => |tuple| {
3365 var offset: u64 = 0;
3366 var big_align: u32 = 0;
3159 return std.mem.alignForwardGeneric(u64, it.offset, @max(it.big_align, 1));
3160 },
33673161
3368 for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
3369 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) {
3370 // comptime field
3371 if (i == index) return offset;
3372 continue;
3373 }
3162 .anon_struct_type => |tuple| {
3163 var offset: u64 = 0;
3164 var big_align: u32 = 0;
33743165
3375 const field_align = field_ty.toType().abiAlignment(mod);
3376 big_align = @max(big_align, field_align);
3377 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
3166 for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
3167 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) {
3168 // comptime field
33783169 if (i == index) return offset;
3379 offset += field_ty.toType().abiSize(mod);
3170 continue;
33803171 }
3381 offset = std.mem.alignForwardGeneric(u64, offset, @max(big_align, 1));
3382 return offset;
3383 },
33843172
3385 .union_type => |union_type| {
3386 if (!union_type.hasTag())
3387 return 0;
3388 const union_obj = mod.unionPtr(union_type.index);
3389 const layout = union_obj.getLayout(mod, true);
3390 if (layout.tag_align >= layout.payload_align) {
3391 // {Tag, Payload}
3392 return std.mem.alignForwardGeneric(u64, layout.tag_size, layout.payload_align);
3393 } else {
3394 // {Payload, Tag}
3395 return 0;
3396 }
3397 },
3173 const field_align = field_ty.toType().abiAlignment(mod);
3174 big_align = @max(big_align, field_align);
3175 offset = std.mem.alignForwardGeneric(u64, offset, field_align);
3176 if (i == index) return offset;
3177 offset += field_ty.toType().abiSize(mod);
3178 }
3179 offset = std.mem.alignForwardGeneric(u64, offset, @max(big_align, 1));
3180 return offset;
3181 },
33983182
3399 else => unreachable,
3183 .union_type => |union_type| {
3184 if (!union_type.hasTag())
3185 return 0;
3186 const union_obj = mod.unionPtr(union_type.index);
3187 const layout = union_obj.getLayout(mod, true);
3188 if (layout.tag_align >= layout.payload_align) {
3189 // {Tag, Payload}
3190 return std.mem.alignForwardGeneric(u64, layout.tag_size, layout.payload_align);
3191 } else {
3192 // {Payload, Tag}
3193 return 0;
3194 }
34003195 },
3196
3197 else => unreachable,
34013198 }
34023199 }
34033200
......@@ -3445,25 +3242,6 @@ pub const Type = struct {
34453242 return ty.ip_index == .generic_poison_type;
34463243 }
34473244
3448 /// This enum does not directly correspond to `std.builtin.TypeId` because
3449 /// it has extra enum tags in it, as a way of using less memory. For example,
3450 /// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types
3451 /// but with different alignment values, in this data structure they are represented
3452 /// with different enum tags, because the the former requires more payload data than the latter.
3453 /// See `zigTypeTag` for the function that corresponds to `std.builtin.TypeId`.
3454 pub const Tag = enum(usize) {
3455 /// This is a special value that tracks a set of types that have been stored
3456 /// to an inferred allocation. It does not support most of the normal type queries.
3457 /// However it does respond to `isConstPtr`, `ptrSize`, `zigTypeTag`, etc.
3458 inferred_alloc_mut,
3459 /// Same as `inferred_alloc_mut` but the local is `var` not `const`.
3460 inferred_alloc_const, // See last_no_payload_tag below.
3461 // After this, the tag requires a payload.
3462
3463 pub const last_no_payload_tag = Tag.inferred_alloc_const;
3464 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
3465 };
3466
34673245 pub fn isTuple(ty: Type, mod: *Module) bool {
34683246 return switch (ty.ip_index) {
34693247 .none => false,
......@@ -3511,14 +3289,9 @@ pub const Type = struct {
35113289 };
35123290 }
35133291
3514 /// The sub-types are named after what fields they contain.
35153292 pub const Payload = struct {
3516 tag: Tag,
3517
35183293 /// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
35193294 pub const Pointer = struct {
3520 data: Data,
3521
35223295 pub const Data = struct {
35233296 pointee_type: Type,
35243297 sentinel: ?Value = null,
......@@ -3568,64 +3341,60 @@ pub const Type = struct {
35683341 };
35693342 };
35703343
3571 pub const @"u1": Type = .{ .ip_index = .u1_type, .legacy = undefined };
3572 pub const @"u8": Type = .{ .ip_index = .u8_type, .legacy = undefined };
3573 pub const @"u16": Type = .{ .ip_index = .u16_type, .legacy = undefined };
3574 pub const @"u29": Type = .{ .ip_index = .u29_type, .legacy = undefined };
3575 pub const @"u32": Type = .{ .ip_index = .u32_type, .legacy = undefined };
3576 pub const @"u64": Type = .{ .ip_index = .u64_type, .legacy = undefined };
3577 pub const @"u128": Type = .{ .ip_index = .u128_type, .legacy = undefined };
3578
3579 pub const @"i8": Type = .{ .ip_index = .i8_type, .legacy = undefined };
3580 pub const @"i16": Type = .{ .ip_index = .i16_type, .legacy = undefined };
3581 pub const @"i32": Type = .{ .ip_index = .i32_type, .legacy = undefined };
3582 pub const @"i64": Type = .{ .ip_index = .i64_type, .legacy = undefined };
3583 pub const @"i128": Type = .{ .ip_index = .i128_type, .legacy = undefined };
3584
3585 pub const @"f16": Type = .{ .ip_index = .f16_type, .legacy = undefined };
3586 pub const @"f32": Type = .{ .ip_index = .f32_type, .legacy = undefined };
3587 pub const @"f64": Type = .{ .ip_index = .f64_type, .legacy = undefined };
3588 pub const @"f80": Type = .{ .ip_index = .f80_type, .legacy = undefined };
3589 pub const @"f128": Type = .{ .ip_index = .f128_type, .legacy = undefined };
3590
3591 pub const @"bool": Type = .{ .ip_index = .bool_type, .legacy = undefined };
3592 pub const @"usize": Type = .{ .ip_index = .usize_type, .legacy = undefined };
3593 pub const @"isize": Type = .{ .ip_index = .isize_type, .legacy = undefined };
3594 pub const @"comptime_int": Type = .{ .ip_index = .comptime_int_type, .legacy = undefined };
3595 pub const @"comptime_float": Type = .{ .ip_index = .comptime_float_type, .legacy = undefined };
3596 pub const @"void": Type = .{ .ip_index = .void_type, .legacy = undefined };
3597 pub const @"type": Type = .{ .ip_index = .type_type, .legacy = undefined };
3598 pub const @"anyerror": Type = .{ .ip_index = .anyerror_type, .legacy = undefined };
3599 pub const @"anyopaque": Type = .{ .ip_index = .anyopaque_type, .legacy = undefined };
3600 pub const @"anyframe": Type = .{ .ip_index = .anyframe_type, .legacy = undefined };
3601 pub const @"null": Type = .{ .ip_index = .null_type, .legacy = undefined };
3602 pub const @"undefined": Type = .{ .ip_index = .undefined_type, .legacy = undefined };
3603 pub const @"noreturn": Type = .{ .ip_index = .noreturn_type, .legacy = undefined };
3604
3605 pub const @"c_char": Type = .{ .ip_index = .c_char_type, .legacy = undefined };
3606 pub const @"c_short": Type = .{ .ip_index = .c_short_type, .legacy = undefined };
3607 pub const @"c_ushort": Type = .{ .ip_index = .c_ushort_type, .legacy = undefined };
3608 pub const @"c_int": Type = .{ .ip_index = .c_int_type, .legacy = undefined };
3609 pub const @"c_uint": Type = .{ .ip_index = .c_uint_type, .legacy = undefined };
3610 pub const @"c_long": Type = .{ .ip_index = .c_long_type, .legacy = undefined };
3611 pub const @"c_ulong": Type = .{ .ip_index = .c_ulong_type, .legacy = undefined };
3612 pub const @"c_longlong": Type = .{ .ip_index = .c_longlong_type, .legacy = undefined };
3613 pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type, .legacy = undefined };
3614 pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type, .legacy = undefined };
3615
3616 pub const const_slice_u8: Type = .{ .ip_index = .const_slice_u8_type, .legacy = undefined };
3617 pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type, .legacy = undefined };
3344 pub const @"u1": Type = .{ .ip_index = .u1_type };
3345 pub const @"u8": Type = .{ .ip_index = .u8_type };
3346 pub const @"u16": Type = .{ .ip_index = .u16_type };
3347 pub const @"u29": Type = .{ .ip_index = .u29_type };
3348 pub const @"u32": Type = .{ .ip_index = .u32_type };
3349 pub const @"u64": Type = .{ .ip_index = .u64_type };
3350 pub const @"u128": Type = .{ .ip_index = .u128_type };
3351
3352 pub const @"i8": Type = .{ .ip_index = .i8_type };
3353 pub const @"i16": Type = .{ .ip_index = .i16_type };
3354 pub const @"i32": Type = .{ .ip_index = .i32_type };
3355 pub const @"i64": Type = .{ .ip_index = .i64_type };
3356 pub const @"i128": Type = .{ .ip_index = .i128_type };
3357
3358 pub const @"f16": Type = .{ .ip_index = .f16_type };
3359 pub const @"f32": Type = .{ .ip_index = .f32_type };
3360 pub const @"f64": Type = .{ .ip_index = .f64_type };
3361 pub const @"f80": Type = .{ .ip_index = .f80_type };
3362 pub const @"f128": Type = .{ .ip_index = .f128_type };
3363
3364 pub const @"bool": Type = .{ .ip_index = .bool_type };
3365 pub const @"usize": Type = .{ .ip_index = .usize_type };
3366 pub const @"isize": Type = .{ .ip_index = .isize_type };
3367 pub const @"comptime_int": Type = .{ .ip_index = .comptime_int_type };
3368 pub const @"comptime_float": Type = .{ .ip_index = .comptime_float_type };
3369 pub const @"void": Type = .{ .ip_index = .void_type };
3370 pub const @"type": Type = .{ .ip_index = .type_type };
3371 pub const @"anyerror": Type = .{ .ip_index = .anyerror_type };
3372 pub const @"anyopaque": Type = .{ .ip_index = .anyopaque_type };
3373 pub const @"anyframe": Type = .{ .ip_index = .anyframe_type };
3374 pub const @"null": Type = .{ .ip_index = .null_type };
3375 pub const @"undefined": Type = .{ .ip_index = .undefined_type };
3376 pub const @"noreturn": Type = .{ .ip_index = .noreturn_type };
3377
3378 pub const @"c_char": Type = .{ .ip_index = .c_char_type };
3379 pub const @"c_short": Type = .{ .ip_index = .c_short_type };
3380 pub const @"c_ushort": Type = .{ .ip_index = .c_ushort_type };
3381 pub const @"c_int": Type = .{ .ip_index = .c_int_type };
3382 pub const @"c_uint": Type = .{ .ip_index = .c_uint_type };
3383 pub const @"c_long": Type = .{ .ip_index = .c_long_type };
3384 pub const @"c_ulong": Type = .{ .ip_index = .c_ulong_type };
3385 pub const @"c_longlong": Type = .{ .ip_index = .c_longlong_type };
3386 pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type };
3387 pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type };
3388
3389 pub const const_slice_u8: Type = .{ .ip_index = .const_slice_u8_type };
3390 pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type };
36183391 pub const single_const_pointer_to_comptime_int: Type = .{
36193392 .ip_index = .single_const_pointer_to_comptime_int_type,
3620 .legacy = undefined,
3621 };
3622 pub const const_slice_u8_sentinel_0: Type = .{
3623 .ip_index = .const_slice_u8_sentinel_0_type,
3624 .legacy = undefined,
36253393 };
3626 pub const empty_struct_literal: Type = .{ .ip_index = .empty_struct_type, .legacy = undefined };
3394 pub const const_slice_u8_sentinel_0: Type = .{ .ip_index = .const_slice_u8_sentinel_0_type };
3395 pub const empty_struct_literal: Type = .{ .ip_index = .empty_struct_type };
36273396
3628 pub const generic_poison: Type = .{ .ip_index = .generic_poison_type, .legacy = undefined };
3397 pub const generic_poison: Type = .{ .ip_index = .generic_poison_type };
36293398
36303399 pub const err_int = Type.u16;
36313400
......@@ -3709,33 +3478,4 @@ pub const Type = struct {
37093478 /// This is only used for comptime asserts. Bump this number when you make a change
37103479 /// to packed struct layout to find out all the places in the codebase you need to edit!
37113480 pub const packed_struct_layout_version = 2;
3712
3713 /// This function is used in the debugger pretty formatters in tools/ to fetch the
3714 /// Tag to Payload mapping to facilitate fancy debug printing for this type.
3715 fn dbHelper(self: *Type, tag_to_payload_map: *map: {
3716 const tags = @typeInfo(Tag).Enum.fields;
3717 var fields: [tags.len]std.builtin.Type.StructField = undefined;
3718 for (&fields, tags) |*field, t| field.* = .{
3719 .name = t.name,
3720 .type = *if (t.value < Tag.no_payload_count) void else @field(Tag, t.name).Type(),
3721 .default_value = null,
3722 .is_comptime = false,
3723 .alignment = 0,
3724 };
3725 break :map @Type(.{ .Struct = .{
3726 .layout = .Extern,
3727 .fields = &fields,
3728 .decls = &.{},
3729 .is_tuple = false,
3730 } });
3731 }) void {
3732 _ = self;
3733 _ = tag_to_payload_map;
3734 }
3735
3736 comptime {
3737 if (builtin.mode == .Debug) {
3738 _ = &dbHelper;
3739 }
3740 }
37413481};
src/value.zig+2-6
......@@ -2159,9 +2159,7 @@ pub const Value = struct {
21592159 .Null,
21602160 => {},
21612161
2162 .Type => {
2163 return val.toType().hashWithHasher(hasher, mod);
2164 },
2162 .Type => unreachable, // handled via ip_index check above
21652163 .Float => {
21662164 // For hash/eql purposes, we treat floats as their IEEE integer representation.
21672165 switch (ty.floatBits(mod.getTarget())) {
......@@ -2310,9 +2308,7 @@ pub const Value = struct {
23102308 .Null,
23112309 .Struct, // It sure would be nice to do something clever with structs.
23122310 => |zig_type_tag| std.hash.autoHash(hasher, zig_type_tag),
2313 .Type => {
2314 val.toType().hashWithHasher(hasher, mod);
2315 },
2311 .Type => unreachable, // handled above with the ip_index check
23162312 .Float, .ComptimeFloat => std.hash.autoHash(hasher, @bitCast(u128, val.toFloat(f128, mod))),
23172313 .Bool, .Int, .ComptimeInt, .Pointer, .Fn => switch (val.tag()) {
23182314 .slice => {