authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-12 13:32:14-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-12 20:08:56-04:00
logcb6201715a7bcae2b278811186afc17a697b25f7
tree30db7b0844d0769b87664e83164f734fae1a9627
parent7e2b6b0f1bc5877f11c50a217dd88c11481bbad4

InternPool: prevent anon struct UAF bugs with type safety

Instead of using actual slices for InternPool.Key.AnonStructType, this commit changes to use Slice types instead, which store a long-lived index rather than a pointer. This is a follow-up to 7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b.

10 files changed, 248 insertions(+), 178 deletions(-)

src/InternPool.zig+116-80
......@@ -373,11 +373,11 @@ pub const Key = union(enum) {
373373 };
374374
375375 pub const AnonStructType = struct {
376 types: []const Index,
376 types: Index.Slice,
377377 /// This may be empty, indicating this is a tuple.
378 names: []const NullTerminatedString,
378 names: NullTerminatedString.Slice,
379379 /// These elements may be `none`, indicating runtime-known.
380 values: []const Index,
380 values: Index.Slice,
381381
382382 pub fn isTuple(self: AnonStructType) bool {
383383 return self.names.len == 0;
......@@ -1020,9 +1020,9 @@ pub const Key = union(enum) {
10201020
10211021 .anon_struct_type => |anon_struct_type| {
10221022 var hasher = Hash.init(seed);
1023 for (anon_struct_type.types) |elem| std.hash.autoHash(&hasher, elem);
1024 for (anon_struct_type.values) |elem| std.hash.autoHash(&hasher, elem);
1025 for (anon_struct_type.names) |elem| std.hash.autoHash(&hasher, elem);
1023 for (anon_struct_type.types.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
1024 for (anon_struct_type.values.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
1025 for (anon_struct_type.names.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
10261026 return hasher.final();
10271027 },
10281028
......@@ -1352,9 +1352,9 @@ pub const Key = union(enum) {
13521352 },
13531353 .anon_struct_type => |a_info| {
13541354 const b_info = b.anon_struct_type;
1355 return std.mem.eql(Index, a_info.types, b_info.types) and
1356 std.mem.eql(Index, a_info.values, b_info.values) and
1357 std.mem.eql(NullTerminatedString, a_info.names, b_info.names);
1355 return std.mem.eql(Index, a_info.types.get(ip), b_info.types.get(ip)) and
1356 std.mem.eql(Index, a_info.values.get(ip), b_info.values.get(ip)) and
1357 std.mem.eql(NullTerminatedString, a_info.names.get(ip), b_info.names.get(ip));
13581358 },
13591359 .error_set_type => |a_info| {
13601360 const b_info = b.error_set_type;
......@@ -2113,9 +2113,9 @@ pub const static_keys = [_]Key{
21132113
21142114 // empty_struct_type
21152115 .{ .anon_struct_type = .{
2116 .types = &.{},
2117 .names = &.{},
2118 .values = &.{},
2116 .types = .{ .start = 0, .len = 0 },
2117 .names = .{ .start = 0, .len = 0 },
2118 .values = .{ .start = 0, .len = 0 },
21192119 } },
21202120
21212121 .{ .simple_value = .undefined },
......@@ -3025,7 +3025,17 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {
30253025
30263026 // This inserts all the statically-known values into the intern pool in the
30273027 // order expected.
3028 for (static_keys) |key| _ = ip.get(gpa, key) catch unreachable;
3028 for (static_keys[0..@intFromEnum(Index.empty_struct_type)]) |key| {
3029 _ = ip.get(gpa, key) catch unreachable;
3030 }
3031 _ = ip.getAnonStructType(gpa, .{
3032 .types = &.{},
3033 .names = &.{},
3034 .values = &.{},
3035 }) catch unreachable;
3036 for (static_keys[@intFromEnum(Index.empty_struct_type) + 1 ..]) |key| {
3037 _ = ip.get(gpa, key) catch unreachable;
3038 }
30293039
30303040 if (std.debug.runtime_safety) {
30313041 // Sanity check.
......@@ -3155,30 +3165,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
31553165 .namespace = @as(Module.Namespace.Index, @enumFromInt(data)).toOptional(),
31563166 } },
31573167
3158 .type_struct_anon => {
3159 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, data);
3160 const fields_len = type_struct_anon.data.fields_len;
3161 const types = ip.extra.items[type_struct_anon.end..][0..fields_len];
3162 const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len];
3163 const names = ip.extra.items[type_struct_anon.end + 2 * fields_len ..][0..fields_len];
3164 return .{ .anon_struct_type = .{
3165 .types = @ptrCast(types),
3166 .values = @ptrCast(values),
3167 .names = @ptrCast(names),
3168 } };
3169 },
3170 .type_tuple_anon => {
3171 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, data);
3172 const fields_len = type_struct_anon.data.fields_len;
3173 const types = ip.extra.items[type_struct_anon.end..][0..fields_len];
3174 const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len];
3175 return .{ .anon_struct_type = .{
3176 .types = @ptrCast(types),
3177 .values = @ptrCast(values),
3178 .names = &.{},
3179 } };
3180 },
3181
3168 .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(ip, data) },
3169 .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(ip, data) },
31823170 .type_union => .{ .union_type = extraUnionType(ip, data) },
31833171
31843172 .type_enum_auto => {
......@@ -3577,6 +3565,44 @@ fn extraUnionType(ip: *const InternPool, extra_index: u32) Key.UnionType {
35773565 };
35783566}
35793567
3568fn extraTypeStructAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {
3569 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);
3570 const fields_len = type_struct_anon.data.fields_len;
3571 return .{
3572 .types = .{
3573 .start = type_struct_anon.end,
3574 .len = fields_len,
3575 },
3576 .values = .{
3577 .start = type_struct_anon.end + fields_len,
3578 .len = fields_len,
3579 },
3580 .names = .{
3581 .start = type_struct_anon.end + fields_len + fields_len,
3582 .len = fields_len,
3583 },
3584 };
3585}
3586
3587fn extraTypeTupleAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {
3588 const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);
3589 const fields_len = type_struct_anon.data.fields_len;
3590 return .{
3591 .types = .{
3592 .start = type_struct_anon.end,
3593 .len = fields_len,
3594 },
3595 .values = .{
3596 .start = type_struct_anon.end + fields_len,
3597 .len = fields_len,
3598 },
3599 .names = .{
3600 .start = 0,
3601 .len = 0,
3602 },
3603 };
3604}
3605
35803606fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {
35813607 const type_function = ip.extraDataTrail(Tag.TypeFunction, extra_index);
35823608 var index: usize = type_function.end;
......@@ -3864,44 +3890,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
38643890 });
38653891 },
38663892
3867 .anon_struct_type => |anon_struct_type| {
3868 assert(anon_struct_type.types.len == anon_struct_type.values.len);
3869 for (anon_struct_type.types) |elem| assert(elem != .none);
3870
3871 const fields_len: u32 = @intCast(anon_struct_type.types.len);
3872 if (anon_struct_type.names.len == 0) {
3873 try ip.extra.ensureUnusedCapacity(
3874 gpa,
3875 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 2),
3876 );
3877 ip.items.appendAssumeCapacity(.{
3878 .tag = .type_tuple_anon,
3879 .data = ip.addExtraAssumeCapacity(TypeStructAnon{
3880 .fields_len = fields_len,
3881 }),
3882 });
3883 ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.types));
3884 ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.values));
3885 return @enumFromInt(ip.items.len - 1);
3886 }
3887
3888 assert(anon_struct_type.names.len == anon_struct_type.types.len);
3889
3890 try ip.extra.ensureUnusedCapacity(
3891 gpa,
3892 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
3893 );
3894 ip.items.appendAssumeCapacity(.{
3895 .tag = .type_struct_anon,
3896 .data = ip.addExtraAssumeCapacity(TypeStructAnon{
3897 .fields_len = fields_len,
3898 }),
3899 });
3900 ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.types));
3901 ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.values));
3902 ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.names));
3903 return @enumFromInt(ip.items.len - 1);
3904 },
3893 .anon_struct_type => unreachable, // use getAnonStructType() instead
39053894
39063895 .union_type => unreachable, // use getUnionType() instead
39073896
......@@ -4408,7 +4397,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
44084397 }
44094398 },
44104399 .anon_struct_type => |anon_struct_type| {
4411 for (aggregate.storage.values(), anon_struct_type.types) |elem, ty| {
4400 for (aggregate.storage.values(), anon_struct_type.types.get(ip)) |elem, ty| {
44124401 assert(ip.typeOf(elem) == ty);
44134402 }
44144403 },
......@@ -4426,7 +4415,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
44264415 switch (ty_key) {
44274416 .anon_struct_type => |anon_struct_type| opv: {
44284417 switch (aggregate.storage) {
4429 .bytes => |bytes| for (anon_struct_type.values, bytes) |value, byte| {
4418 .bytes => |bytes| for (anon_struct_type.values.get(ip), bytes) |value, byte| {
44304419 if (value != ip.getIfExists(.{ .int = .{
44314420 .ty = .u8_type,
44324421 .storage = .{ .u64 = byte },
......@@ -4434,10 +4423,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
44344423 },
44354424 .elems => |elems| if (!std.mem.eql(
44364425 Index,
4437 anon_struct_type.values,
4426 anon_struct_type.values.get(ip),
44384427 elems,
44394428 )) break :opv,
4440 .repeated_elem => |elem| for (anon_struct_type.values) |value| {
4429 .repeated_elem => |elem| for (anon_struct_type.values.get(ip)) |value| {
44414430 if (value != elem) break :opv;
44424431 },
44434432 }
......@@ -4646,6 +4635,53 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
46464635 return @enumFromInt(ip.items.len - 1);
46474636}
46484637
4638pub const AnonStructTypeInit = struct {
4639 types: []const Index,
4640 /// This may be empty, indicating this is a tuple.
4641 names: []const NullTerminatedString,
4642 /// These elements may be `none`, indicating runtime-known.
4643 values: []const Index,
4644};
4645
4646pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeInit) Allocator.Error!Index {
4647 assert(ini.types.len == ini.values.len);
4648 for (ini.types) |elem| assert(elem != .none);
4649
4650 const prev_extra_len = ip.extra.items.len;
4651 const fields_len: u32 = @intCast(ini.types.len);
4652
4653 try ip.extra.ensureUnusedCapacity(
4654 gpa,
4655 @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
4656 );
4657 try ip.items.ensureUnusedCapacity(gpa, 1);
4658
4659 const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{
4660 .fields_len = fields_len,
4661 });
4662 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.types));
4663 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));
4664
4665 const adapter: KeyAdapter = .{ .intern_pool = ip };
4666 const key: Key = .{
4667 .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(ip, extra_index) else k: {
4668 assert(ini.names.len == ini.types.len);
4669 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));
4670 break :k extraTypeStructAnon(ip, extra_index);
4671 },
4672 };
4673 const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);
4674 if (gop.found_existing) {
4675 ip.extra.items.len = prev_extra_len;
4676 return @enumFromInt(gop.index);
4677 }
4678 ip.items.appendAssumeCapacity(.{
4679 .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,
4680 .data = extra_index,
4681 });
4682 return @enumFromInt(ip.items.len - 1);
4683}
4684
46494685/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.
46504686pub const GetFuncTypeKey = struct {
46514687 param_types: []Index,
......@@ -6056,7 +6092,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
60566092 for (agg_elems, 0..) |*elem, i| {
60576093 const new_elem_ty = switch (ip.indexToKey(new_ty)) {
60586094 inline .array_type, .vector_type => |seq_type| seq_type.child,
6059 .anon_struct_type => |anon_struct_type| anon_struct_type.types[i],
6095 .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[i],
60606096 .struct_type => |struct_type| ip.structPtr(struct_type.index.unwrap().?)
60616097 .fields.values()[i].ty.toIntern(),
60626098 else => unreachable,
src/Sema.zig+60-51
......@@ -8052,11 +8052,12 @@ fn instantiateGenericCall(
80528052
80538053fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
80548054 const mod = sema.mod;
8055 const tuple = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
8055 const ip = &mod.intern_pool;
8056 const tuple = switch (ip.indexToKey(ty.toIntern())) {
80568057 .anon_struct_type => |tuple| tuple,
80578058 else => return,
80588059 };
8059 for (tuple.types, tuple.values) |field_ty, field_val| {
8060 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
80608061 try sema.resolveTupleLazyValues(block, src, field_ty.toType());
80618062 if (field_val == .none) continue;
80628063 // TODO: mutate in intern pool
......@@ -12929,7 +12930,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1292912930 },
1293012931 .anon_struct_type => |anon_struct| {
1293112932 if (anon_struct.names.len != 0) {
12932 break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, field_name) != null;
12933 break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names.get(ip), field_name) != null;
1293312934 } else {
1293412935 const field_index = field_name.toUnsigned(ip) orelse break :hf false;
1293512936 break :hf field_index < ty.structFieldCount(mod);
......@@ -13558,11 +13559,11 @@ fn analyzeTupleCat(
1355813559 break :rs runtime_src;
1355913560 };
1356013561
13561 const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
13562 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{
1356213563 .types = types,
1356313564 .values = values,
1356413565 .names = &.{},
13565 } });
13566 });
1356613567
1356713568 const runtime_src = opt_runtime_src orelse {
1356813569 const tuple_val = try mod.intern(.{ .aggregate = .{
......@@ -13889,11 +13890,11 @@ fn analyzeTupleMul(
1388913890 break :rs runtime_src;
1389013891 };
1389113892
13892 const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
13893 const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{
1389313894 .types = types,
1389413895 .values = values,
1389513896 .names = &.{},
13896 } });
13897 });
1389713898
1389813899 const runtime_src = opt_runtime_src orelse {
1389913900 const tuple_val = try mod.intern(.{ .aggregate = .{
......@@ -15217,6 +15218,7 @@ fn zirOverflowArithmetic(
1521715218 const lhs_ty = sema.typeOf(uncasted_lhs);
1521815219 const rhs_ty = sema.typeOf(uncasted_rhs);
1521915220 const mod = sema.mod;
15221 const ip = &mod.intern_pool;
1522015222
1522115223 try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
1522215224
......@@ -15244,7 +15246,7 @@ fn zirOverflowArithmetic(
1524415246 const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
1524515247
1524615248 const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
15247 const overflow_ty = mod.intern_pool.indexToKey(tuple_ty.toIntern()).anon_struct_type.types[1].toType();
15249 const overflow_ty = ip.indexToKey(tuple_ty.toIntern()).anon_struct_type.types.get(ip)[1].toType();
1524815250
1524915251 var result: struct {
1525015252 inst: Air.Inst.Ref = .none,
......@@ -15418,6 +15420,7 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {
1541815420
1541915421fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
1542015422 const mod = sema.mod;
15423 const ip = &mod.intern_pool;
1542115424 const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{
1542215425 .len = ty.vectorLen(mod),
1542315426 .child = .u1_type,
......@@ -15425,11 +15428,11 @@ fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
1542515428
1542615429 const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };
1542715430 const values = [2]InternPool.Index{ .none, .none };
15428 const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
15431 const tuple_ty = try ip.getAnonStructType(mod.gpa, .{
1542915432 .types = &types,
1543015433 .values = &values,
1543115434 .names = &.{},
15432 } });
15435 });
1543315436 return tuple_ty.toType();
1543415437}
1543515438
......@@ -17578,15 +17581,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1757817581 struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
1757917582 for (struct_field_vals, 0..) |*struct_field_val, i| {
1758017583 const anon_struct_type = ip.indexToKey(ty.toIntern()).anon_struct_type;
17581 const field_ty = anon_struct_type.types[i];
17582 const field_val = anon_struct_type.values[i];
17584 const field_ty = anon_struct_type.types.get(ip)[i];
17585 const field_val = anon_struct_type.values.get(ip)[i];
1758317586 const name_val = v: {
1758417587 var anon_decl = try block.startAnonDecl();
1758517588 defer anon_decl.deinit();
1758617589 // TODO: write something like getCoercedInts to avoid needing to dupe
1758717590 const bytes = if (tuple.names.len != 0)
1758817591 // https://github.com/ziglang/zig/issues/15709
17589 try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names[i]))
17592 try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip)[i]))
1759017593 else
1759117594 try std.fmt.allocPrint(sema.arena, "{d}", .{i});
1759217595 const new_decl_ty = try mod.arrayType(.{
......@@ -19254,7 +19257,7 @@ fn finishStructInit(
1925419257
1925519258 switch (ip.indexToKey(struct_ty.toIntern())) {
1925619259 .anon_struct_type => |anon_struct| {
19257 for (anon_struct.values, 0..) |default_val, i| {
19260 for (anon_struct.values.get(ip), 0..) |default_val, i| {
1925819261 if (field_inits[i] != .none) continue;
1925919262
1926019263 if (default_val == .none) {
......@@ -19266,7 +19269,7 @@ fn finishStructInit(
1926619269 root_msg = try sema.errMsg(block, init_src, template, .{i});
1926719270 }
1926819271 } else {
19269 const field_name = anon_struct.names[i];
19272 const field_name = anon_struct.names.get(ip)[i];
1927019273 const template = "missing struct field: {}";
1927119274 const args = .{field_name.fmt(ip)};
1927219275 if (root_msg) |msg| {
......@@ -19395,6 +19398,7 @@ fn structInitAnon(
1939519398) CompileError!Air.Inst.Ref {
1939619399 const mod = sema.mod;
1939719400 const gpa = sema.gpa;
19401 const ip = &mod.intern_pool;
1939819402 const zir_datas = sema.code.instructions.items(.data);
1939919403
1940019404 const types = try sema.arena.alloc(InternPool.Index, extra_data.fields_len);
......@@ -19465,11 +19469,11 @@ fn structInitAnon(
1946519469 break :rs runtime_index;
1946619470 };
1946719471
19468 const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
19472 const tuple_ty = try ip.getAnonStructType(gpa, .{
1946919473 .names = fields.keys(),
1947019474 .types = types,
1947119475 .values = values,
19472 } });
19476 });
1947319477
1947419478 const runtime_index = opt_runtime_index orelse {
1947519479 const tuple_val = try mod.intern(.{ .aggregate = .{
......@@ -19688,6 +19692,8 @@ fn arrayInitAnon(
1968819692 is_ref: bool,
1968919693) CompileError!Air.Inst.Ref {
1969019694 const mod = sema.mod;
19695 const gpa = sema.gpa;
19696 const ip = &mod.intern_pool;
1969119697
1969219698 const types = try sema.arena.alloc(InternPool.Index, operands.len);
1969319699 const values = try sema.arena.alloc(InternPool.Index, operands.len);
......@@ -19701,7 +19707,7 @@ fn arrayInitAnon(
1970119707 if (types[i].toType().zigTypeTag(mod) == .Opaque) {
1970219708 const msg = msg: {
1970319709 const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
19704 errdefer msg.destroy(sema.gpa);
19710 errdefer msg.destroy(gpa);
1970519711
1970619712 try sema.addDeclaredHereNote(msg, types[i].toType());
1970719713 break :msg msg;
......@@ -19718,11 +19724,11 @@ fn arrayInitAnon(
1971819724 break :rs runtime_src;
1971919725 };
1972019726
19721 const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
19727 const tuple_ty = try ip.getAnonStructType(gpa, .{
1972219728 .types = types,
1972319729 .values = values,
1972419730 .names = &.{},
19725 } });
19731 });
1972619732
1972719733 const runtime_src = opt_runtime_src orelse {
1972819734 const tuple_val = try mod.intern(.{ .aggregate = .{
......@@ -19832,7 +19838,7 @@ fn fieldType(
1983219838 .Struct => switch (ip.indexToKey(cur_ty.toIntern())) {
1983319839 .anon_struct_type => |anon_struct| {
1983419840 const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);
19835 return Air.internedToRef(anon_struct.types[field_index]);
19841 return Air.internedToRef(anon_struct.types.get(ip)[field_index]);
1983619842 },
1983719843 .struct_type => |struct_type| {
1983819844 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
......@@ -30574,13 +30580,14 @@ fn coerceAnonStructToUnion(
3057430580 inst_src: LazySrcLoc,
3057530581) !Air.Inst.Ref {
3057630582 const mod = sema.mod;
30583 const ip = &mod.intern_pool;
3057730584 const inst_ty = sema.typeOf(inst);
3057830585 const field_info: union(enum) {
3057930586 name: InternPool.NullTerminatedString,
3058030587 count: usize,
30581 } = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
30588 } = switch (ip.indexToKey(inst_ty.toIntern())) {
3058230589 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1)
30583 .{ .name = anon_struct_type.names[0] }
30590 .{ .name = anon_struct_type.names.get(ip)[0] }
3058430591 else
3058530592 .{ .count = anon_struct_type.names.len },
3058630593 .struct_type => |struct_type| name: {
......@@ -30876,7 +30883,7 @@ fn coerceTupleToStruct(
3087630883 // https://github.com/ziglang/zig/issues/15709
3087730884 const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
3087830885 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
30879 anon_struct_type.names[field_i]
30886 anon_struct_type.names.get(ip)[field_i]
3088030887 else
3088130888 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
3088230889 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
......@@ -30994,7 +31001,7 @@ fn coerceTupleToTuple(
3099431001 // https://github.com/ziglang/zig/issues/15709
3099531002 const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
3099631003 .anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
30997 anon_struct_type.names[field_i]
31004 anon_struct_type.names.get(ip)[field_i]
3099831005 else
3099931006 try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
3100031007 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
......@@ -31005,12 +31012,12 @@ fn coerceTupleToTuple(
3100531012 return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});
3100631013
3100731014 const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
31008 .anon_struct_type => |anon_struct_type| anon_struct_type.types[field_index_usize].toType(),
31015 .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[field_index_usize].toType(),
3100931016 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty,
3101031017 else => unreachable,
3101131018 };
3101231019 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
31013 .anon_struct_type => |anon_struct_type| anon_struct_type.values[field_index_usize],
31020 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[field_index_usize],
3101431021 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val,
3101531022 else => unreachable,
3101631023 };
......@@ -31048,7 +31055,7 @@ fn coerceTupleToTuple(
3104831055 if (field_ref.* != .none) continue;
3104931056
3105031057 const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
31051 .anon_struct_type => |anon_struct_type| anon_struct_type.values[i],
31058 .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[i],
3105231059 .struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val,
3105331060 else => unreachable,
3105431061 };
......@@ -32855,6 +32862,7 @@ fn resolvePeerTypesInner(
3285532862 peer_vals: []?Value,
3285632863) !PeerResolveResult {
3285732864 const mod = sema.mod;
32865 const ip = &mod.intern_pool;
3285832866
3285932867 var strat_reason: usize = 0;
3286032868 var s: PeerResolveStrategy = .unknown;
......@@ -32912,7 +32920,7 @@ fn resolvePeerTypesInner(
3291232920 .ErrorUnion => blk: {
3291332921 const set_ty = ty.errorUnionSet(mod);
3291432922 ty_ptr.* = ty.errorUnionPayload(mod);
32915 if (val_ptr.*) |eu_val| switch (mod.intern_pool.indexToKey(eu_val.toIntern())) {
32923 if (val_ptr.*) |eu_val| switch (ip.indexToKey(eu_val.toIntern())) {
3291632924 .error_union => |eu| switch (eu.val) {
3291732925 .payload => |payload_ip| val_ptr.* = payload_ip.toValue(),
3291832926 .err_name => val_ptr.* = null,
......@@ -33166,8 +33174,8 @@ fn resolvePeerTypesInner(
3316633174 }).toIntern();
3316733175
3316833176 if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {
33169 const peer_sent = try mod.intern_pool.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);
33170 const ptr_sent = try mod.intern_pool.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);
33177 const peer_sent = try ip.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);
33178 const ptr_sent = try ip.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);
3317133179 if (ptr_sent == peer_sent) {
3317233180 ptr_info.sentinel = ptr_sent;
3317333181 } else {
......@@ -33278,7 +33286,7 @@ fn resolvePeerTypesInner(
3327833286 ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile;
3327933287
3328033288 const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) {
33281 .One => switch (mod.intern_pool.indexToKey(peer_info.child)) {
33289 .One => switch (ip.indexToKey(peer_info.child)) {
3328233290 .array_type => |array_type| array_type.sentinel,
3328333291 else => .none,
3328433292 },
......@@ -33287,7 +33295,7 @@ fn resolvePeerTypesInner(
3328733295 };
3328833296
3328933297 const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) {
33290 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
33298 .One => switch (ip.indexToKey(ptr_info.child)) {
3329133299 .array_type => |array_type| array_type.sentinel,
3329233300 else => .none,
3329333301 },
......@@ -33449,7 +33457,7 @@ fn resolvePeerTypesInner(
3344933457 }
3345033458
3345133459 const sentinel_ty = switch (ptr_info.flags.size) {
33452 .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
33460 .One => switch (ip.indexToKey(ptr_info.child)) {
3345333461 .array_type => |array_type| array_type.child,
3345433462 else => ptr_info.child,
3345533463 },
......@@ -33460,11 +33468,11 @@ fn resolvePeerTypesInner(
3346033468 no_sentinel: {
3346133469 if (peer_sentinel == .none) break :no_sentinel;
3346233470 if (cur_sentinel == .none) break :no_sentinel;
33463 const peer_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);
33464 const cur_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);
33471 const peer_sent_coerced = try ip.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);
33472 const cur_sent_coerced = try ip.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);
3346533473 if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;
3346633474 // Sentinels match
33467 if (ptr_info.flags.size == .One) switch (mod.intern_pool.indexToKey(ptr_info.child)) {
33475 if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) {
3346833476 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
3346933477 .len = array_type.len,
3347033478 .child = array_type.child,
......@@ -33478,7 +33486,7 @@ fn resolvePeerTypesInner(
3347833486 }
3347933487 // Clear existing sentinel
3348033488 ptr_info.sentinel = .none;
33481 switch (mod.intern_pool.indexToKey(ptr_info.child)) {
33489 switch (ip.indexToKey(ptr_info.child)) {
3348233490 .array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
3348333491 .len = array_type.len,
3348433492 .child = array_type.child,
......@@ -33501,7 +33509,7 @@ fn resolvePeerTypesInner(
3350133509 .peer_idx_a = first_idx,
3350233510 .peer_idx_b = other_idx,
3350333511 } },
33504 else => switch (mod.intern_pool.indexToKey(pointee)) {
33512 else => switch (ip.indexToKey(pointee)) {
3350533513 .array_type => |array_type| if (array_type.child == .noreturn_type) return .{ .conflict = .{
3350633514 .peer_idx_a = first_idx,
3350733515 .peer_idx_b = other_idx,
......@@ -33785,7 +33793,7 @@ fn resolvePeerTypesInner(
3378533793 is_tuple = ty.isTuple(mod);
3378633794 field_count = ty.structFieldCount(mod);
3378733795 if (!is_tuple) {
33788 const names = mod.intern_pool.indexToKey(ty.toIntern()).anon_struct_type.names;
33796 const names = ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip);
3378933797 field_names = try sema.arena.dupe(InternPool.NullTerminatedString, names);
3379033798 }
3379133799 continue;
......@@ -33839,7 +33847,7 @@ fn resolvePeerTypesInner(
3383933847 result_buf.* = result;
3384033848 const field_name = if (is_tuple) name: {
3384133849 break :name try std.fmt.allocPrint(sema.arena, "{d}", .{field_idx});
33842 } else try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(field_names[field_idx]));
33850 } else try sema.arena.dupe(u8, ip.stringToSlice(field_names[field_idx]));
3384333851
3384433852 // The error info needs the field types, but we can't reuse sub_peer_tys
3384533853 // since the recursive call may have clobbered it.
......@@ -33892,11 +33900,11 @@ fn resolvePeerTypesInner(
3389233900 field_val.* = if (comptime_val) |v| v.toIntern() else .none;
3389333901 }
3389433902
33895 const final_ty = try mod.intern(.{ .anon_struct_type = .{
33903 const final_ty = try ip.getAnonStructType(mod.gpa, .{
3389633904 .types = field_types,
3389733905 .names = if (is_tuple) &.{} else field_names,
3389833906 .values = field_vals,
33899 } });
33907 });
3390033908
3390133909 return .{ .success = final_ty.toType() };
3390233910 },
......@@ -34491,6 +34499,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
3449134499/// be resolved.
3449234500pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3449334501 const mod = sema.mod;
34502 const ip = &mod.intern_pool;
3449434503 switch (ty.zigTypeTag(mod)) {
3449534504 .Pointer => {
3449634505 return sema.resolveTypeFully(ty.childType(mod));
......@@ -34498,7 +34507,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3449834507 .Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3449934508 .struct_type => return sema.resolveStructFully(ty),
3450034509 .anon_struct_type => |tuple| {
34501 for (tuple.types) |field_ty| {
34510 for (tuple.types.get(ip)) |field_ty| {
3450234511 try sema.resolveTypeFully(field_ty.toType());
3450334512 }
3450434513 },
......@@ -34518,7 +34527,6 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
3451834527 // the function is instantiated.
3451934528 return;
3452034529 }
34521 const ip = &mod.intern_pool;
3452234530 for (0..info.param_types.len) |i| {
3452334531 const param_ty = info.param_types.get(ip)[i];
3452434532 try sema.resolveTypeFully(param_ty.toType());
......@@ -36133,7 +36141,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3613336141 },
3613436142
3613536143 .anon_struct_type => |tuple| {
36136 for (tuple.values) |val| {
36144 for (tuple.values.get(ip)) |val| {
3613736145 if (val == .none) return null;
3613836146 }
3613936147 // In this case the struct has all comptime-known fields and
......@@ -36141,7 +36149,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3614136149 // TODO: write something like getCoercedInts to avoid needing to dupe
3614236150 return (try mod.intern(.{ .aggregate = .{
3614336151 .ty = ty.toIntern(),
36144 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) },
36152 .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) },
3614536153 } })).toValue();
3614636154 },
3614736155
......@@ -36611,7 +36619,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3661136619 }
3661236620 },
3661336621 .anon_struct_type => |tuple| {
36614 for (tuple.types, tuple.values) |field_ty, val| {
36622 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
3661536623 const have_comptime_val = val != .none;
3661636624 if (!have_comptime_val and try sema.typeRequiresComptime(field_ty.toType())) {
3661736625 return true;
......@@ -36784,8 +36792,9 @@ fn anonStructFieldIndex(
3678436792 field_src: LazySrcLoc,
3678536793) !u32 {
3678636794 const mod = sema.mod;
36787 switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
36788 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names, 0..) |name, i| {
36795 const ip = &mod.intern_pool;
36796 switch (ip.indexToKey(struct_ty.toIntern())) {
36797 .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| {
3678936798 if (name == field_name) return @intCast(i);
3679036799 },
3679136800 .struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
......@@ -36798,7 +36807,7 @@ fn anonStructFieldIndex(
3679836807 else => unreachable,
3679936808 }
3680036809 return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{
36801 field_name.fmt(&mod.intern_pool), struct_ty.fmt(sema.mod),
36810 field_name.fmt(ip), struct_ty.fmt(sema.mod),
3680236811 });
3680336812}
3680436813
src/TypedValue.zig+4-3
......@@ -423,6 +423,7 @@ fn printAggregate(
423423 if (level == 0) {
424424 return writer.writeAll(".{ ... }");
425425 }
426 const ip = &mod.intern_pool;
426427 if (ty.zigTypeTag(mod) == .Struct) {
427428 try writer.writeAll(".{");
428429 const max_len = @min(ty.structFieldCount(mod), max_aggregate_items);
......@@ -430,13 +431,13 @@ fn printAggregate(
430431 for (0..max_len) |i| {
431432 if (i != 0) try writer.writeAll(", ");
432433
433 const field_name = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
434 const field_name = switch (ip.indexToKey(ty.toIntern())) {
434435 .struct_type => |x| mod.structPtrUnwrap(x.index).?.fields.keys()[i].toOptional(),
435 .anon_struct_type => |x| if (x.isTuple()) .none else x.names[i].toOptional(),
436 .anon_struct_type => |x| if (x.isTuple()) .none else x.names.get(ip)[i].toOptional(),
436437 else => unreachable,
437438 };
438439
439 if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(&mod.intern_pool)});
440 if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(ip)});
440441 try print(.{
441442 .ty = ty.structFieldType(i, mod),
442443 .val = try val.fieldValue(mod, i),
src/codegen.zig+5-1
......@@ -438,7 +438,11 @@ pub fn generateSymbol(
438438 },
439439 .anon_struct_type => |tuple| {
440440 const struct_begin = code.items.len;
441 for (tuple.types, tuple.values, 0..) |field_ty, comptime_val, index| {
441 for (
442 tuple.types.get(ip),
443 tuple.values.get(ip),
444 0..,
445 ) |field_ty, comptime_val, index| {
442446 if (comptime_val != .none) continue;
443447 if (!field_ty.toType().hasRuntimeBits(mod)) continue;
444448
src/codegen/c.zig+10-4
......@@ -1275,7 +1275,11 @@ pub const DeclGen = struct {
12751275
12761276 try writer.writeByte('{');
12771277 var empty = true;
1278 for (tuple.types, tuple.values, 0..) |field_ty, comptime_ty, field_i| {
1278 for (
1279 tuple.types.get(ip),
1280 tuple.values.get(ip),
1281 0..,
1282 ) |field_ty, comptime_ty, field_i| {
12791283 if (comptime_ty != .none) continue;
12801284 if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
12811285
......@@ -7745,16 +7749,18 @@ fn lowerFnRetTy(ret_ty: Type, mod: *Module) !Type {
77457749 if (ret_ty.ip_index == .noreturn_type) return Type.noreturn;
77467750
77477751 if (lowersToArray(ret_ty, mod)) {
7752 const gpa = mod.gpa;
7753 const ip = &mod.intern_pool;
77487754 const names = [1]InternPool.NullTerminatedString{
7749 try mod.intern_pool.getOrPutString(mod.gpa, "array"),
7755 try ip.getOrPutString(gpa, "array"),
77507756 };
77517757 const types = [1]InternPool.Index{ret_ty.ip_index};
77527758 const values = [1]InternPool.Index{.none};
7753 const interned = try mod.intern(.{ .anon_struct_type = .{
7759 const interned = try ip.getAnonStructType(gpa, .{
77547760 .names = &names,
77557761 .types = &types,
77567762 .values = &values,
7757 } });
7763 });
77587764 return interned.toType();
77597765 }
77607766
src/codegen/llvm.zig+17-8
......@@ -2392,7 +2392,7 @@ pub const Object = struct {
23922392 comptime assert(struct_layout_version == 2);
23932393 var offset: u64 = 0;
23942394
2395 for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
2395 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
23962396 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
23972397
23982398 const field_size = field_ty.toType().abiSize(mod);
......@@ -2401,7 +2401,7 @@ pub const Object = struct {
24012401 offset = field_offset + field_size;
24022402
24032403 const field_name = if (tuple.names.len != 0)
2404 ip.stringToSlice(tuple.names[i])
2404 ip.stringToSlice(tuple.names.get(ip)[i])
24052405 else
24062406 try std.fmt.allocPrintZ(gpa, "{d}", .{i});
24072407 defer if (tuple.names.len == 0) gpa.free(field_name);
......@@ -3325,7 +3325,10 @@ pub const Object = struct {
33253325 var offset: u64 = 0;
33263326 var big_align: u32 = 0;
33273327
3328 for (anon_struct_type.types, anon_struct_type.values) |field_ty, field_val| {
3328 for (
3329 anon_struct_type.types.get(ip),
3330 anon_struct_type.values.get(ip),
3331 ) |field_ty, field_val| {
33293332 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
33303333
33313334 const field_align = field_ty.toType().abiAlignment(mod);
......@@ -3874,7 +3877,11 @@ pub const Object = struct {
38743877 var offset: u64 = 0;
38753878 var big_align: u32 = 0;
38763879 var need_unnamed = false;
3877 for (tuple.types, tuple.values, 0..) |field_ty, field_val, field_index| {
3880 for (
3881 tuple.types.get(ip),
3882 tuple.values.get(ip),
3883 0..,
3884 ) |field_ty, field_val, field_index| {
38783885 if (field_val != .none) continue;
38793886 if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
38803887
......@@ -10537,10 +10544,11 @@ fn llvmField(ty: Type, field_index: usize, mod: *Module) ?LlvmField {
1053710544 var offset: u64 = 0;
1053810545 var big_align: u32 = 0;
1053910546
10540 const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
10547 const ip = &mod.intern_pool;
10548 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
1054110549 .anon_struct_type => |tuple| {
1054210550 var llvm_field_index: c_uint = 0;
10543 for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
10551 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
1054410552 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
1054510553
1054610554 const field_align = field_ty.toType().abiAlignment(mod);
......@@ -11118,6 +11126,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
1111811126 // For tuples and structs, if there are more than this many non-void
1111911127 // fields, then we make it byref, otherwise byval.
1112011128 const max_fields_byval = 0;
11129 const ip = &mod.intern_pool;
1112111130
1112211131 switch (ty.zigTypeTag(mod)) {
1112311132 .Type,
......@@ -11146,10 +11155,10 @@ fn isByRef(ty: Type, mod: *Module) bool {
1114611155 .Struct => {
1114711156 // Packed structs are represented to LLVM as integers.
1114811157 if (ty.containerLayout(mod) == .Packed) return false;
11149 const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
11158 const struct_type = switch (ip.indexToKey(ty.toIntern())) {
1115011159 .anon_struct_type => |tuple| {
1115111160 var count: usize = 0;
11152 for (tuple.types, tuple.values) |field_ty, field_val| {
11161 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
1115311162 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
1115411163
1115511164 count += 1;
src/codegen/spirv.zig+5-5
......@@ -1227,6 +1227,7 @@ pub const DeclGen = struct {
12271227 /// Turn a Zig type into a SPIR-V Type, and return a reference to it.
12281228 fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef {
12291229 const mod = self.module;
1230 const ip = &mod.intern_pool;
12301231 log.debug("resolveType: ty = {}", .{ty.fmt(self.module)});
12311232 const target = self.getTarget();
12321233 switch (ty.zigTypeTag(mod)) {
......@@ -1271,7 +1272,6 @@ pub const DeclGen = struct {
12711272 },
12721273 .Fn => switch (repr) {
12731274 .direct => {
1274 const ip = &mod.intern_pool;
12751275 const fn_info = mod.typeToFunc(ty).?;
12761276 // TODO: Put this somewhere in Sema.zig
12771277 if (fn_info.is_var_args)
......@@ -1333,13 +1333,13 @@ pub const DeclGen = struct {
13331333 } });
13341334 },
13351335 .Struct => {
1336 const struct_ty = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
1336 const struct_ty = switch (ip.indexToKey(ty.toIntern())) {
13371337 .anon_struct_type => |tuple| {
13381338 const member_types = try self.gpa.alloc(CacheRef, tuple.values.len);
13391339 defer self.gpa.free(member_types);
13401340
13411341 var member_index: usize = 0;
1342 for (tuple.types, tuple.values) |field_ty, field_val| {
1342 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
13431343 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
13441344
13451345 member_types[member_index] = try self.resolveType(field_ty.toType(), .indirect);
......@@ -1369,12 +1369,12 @@ pub const DeclGen = struct {
13691369 while (it.next()) |field_and_index| {
13701370 const field = field_and_index.field;
13711371 const index = field_and_index.index;
1372 const field_name = mod.intern_pool.stringToSlice(struct_obj.fields.keys()[index]);
1372 const field_name = ip.stringToSlice(struct_obj.fields.keys()[index]);
13731373 try member_types.append(try self.resolveType(field.ty, .indirect));
13741374 try member_names.append(try self.spv.resolveString(field_name));
13751375 }
13761376
1377 const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(self.module));
1377 const name = ip.stringToSlice(try struct_obj.getFullyQualifiedName(self.module));
13781378
13791379 return try self.spv.resolve(.{ .struct_type = .{
13801380 .name = try self.spv.resolveString(name),
src/link/Dwarf.zig+1-1
......@@ -327,7 +327,7 @@ pub const DeclState = struct {
327327 // DW.AT.name, DW.FORM.string
328328 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
329329
330 for (fields.types, 0..) |field_ty, field_index| {
330 for (fields.types.get(ip), 0..) |field_ty, field_index| {
331331 // DW.AT.member
332332 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
333333 // DW.AT.name, DW.FORM.string
src/type.zig+26-22
......@@ -170,7 +170,8 @@ pub const Type = struct {
170170
171171 /// Prints a name suitable for `@typeName`.
172172 pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
173 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
173 const ip = &mod.intern_pool;
174 switch (ip.indexToKey(ty.toIntern())) {
174175 .int_type => |int_type| {
175176 const sign_char: u8 = switch (int_type.signedness) {
176177 .signed => 'i',
......@@ -257,7 +258,6 @@ pub const Type = struct {
257258 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
258259 },
259260 .error_set_type => |error_set_type| {
260 const ip = &mod.intern_pool;
261261 const names = error_set_type.names;
262262 try writer.writeAll("error{");
263263 for (names.get(ip), 0..) |name, i| {
......@@ -330,13 +330,13 @@ pub const Type = struct {
330330 return writer.writeAll("@TypeOf(.{})");
331331 }
332332 try writer.writeAll("struct{");
333 for (anon_struct.types, anon_struct.values, 0..) |field_ty, val, i| {
333 for (anon_struct.types.get(ip), anon_struct.values.get(ip), 0..) |field_ty, val, i| {
334334 if (i != 0) try writer.writeAll(", ");
335335 if (val != .none) {
336336 try writer.writeAll("comptime ");
337337 }
338338 if (anon_struct.names.len != 0) {
339 try writer.print("{}: ", .{anon_struct.names[i].fmt(&mod.intern_pool)});
339 try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)});
340340 }
341341
342342 try print(field_ty.toType(), writer, mod);
......@@ -587,7 +587,7 @@ pub const Type = struct {
587587 }
588588 },
589589 .anon_struct_type => |tuple| {
590 for (tuple.types, tuple.values) |field_ty, val| {
590 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
591591 if (val != .none) continue; // comptime field
592592 if (try field_ty.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true;
593593 }
......@@ -1055,7 +1055,7 @@ pub const Type = struct {
10551055 },
10561056 .anon_struct_type => |tuple| {
10571057 var big_align: u32 = 0;
1058 for (tuple.types, tuple.values) |field_ty, val| {
1058 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
10591059 if (val != .none) continue; // comptime field
10601060 if (!(field_ty.toType().hasRuntimeBits(mod))) continue;
10611061
......@@ -2155,7 +2155,7 @@ pub const Type = struct {
21552155 pub fn vectorLen(ty: Type, mod: *const Module) u32 {
21562156 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
21572157 .vector_type => |vector_type| vector_type.len,
2158 .anon_struct_type => |tuple| @as(u32, @intCast(tuple.types.len)),
2158 .anon_struct_type => |tuple| @intCast(tuple.types.len),
21592159 else => unreachable,
21602160 };
21612161 }
......@@ -2536,13 +2536,13 @@ pub const Type = struct {
25362536 },
25372537
25382538 .anon_struct_type => |tuple| {
2539 for (tuple.values) |val| {
2539 for (tuple.values.get(ip)) |val| {
25402540 if (val == .none) return null;
25412541 }
25422542 // In this case the struct has all comptime-known fields and
25432543 // therefore has one possible value.
25442544 // TODO: write something like getCoercedInts to avoid needing to dupe
2545 const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values);
2545 const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip));
25462546 defer mod.gpa.free(duped_values);
25472547 return (try mod.intern(.{ .aggregate = .{
25482548 .ty = ty.toIntern(),
......@@ -2732,7 +2732,7 @@ pub const Type = struct {
27322732 },
27332733
27342734 .anon_struct_type => |tuple| {
2735 for (tuple.types, tuple.values) |field_ty, val| {
2735 for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
27362736 const have_comptime_val = val != .none;
27372737 if (!have_comptime_val and field_ty.toType().comptimeOnly(mod)) return true;
27382738 }
......@@ -2996,13 +2996,14 @@ pub const Type = struct {
29962996 }
29972997
29982998 pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
2999 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
2999 const ip = &mod.intern_pool;
3000 return switch (ip.indexToKey(ty.toIntern())) {
30003001 .struct_type => |struct_type| {
30013002 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
30023003 assert(struct_obj.haveFieldTypes());
30033004 return struct_obj.fields.keys()[field_index];
30043005 },
3005 .anon_struct_type => |anon_struct| anon_struct.names[field_index],
3006 .anon_struct_type => |anon_struct| anon_struct.names.get(ip)[field_index],
30063007 else => unreachable,
30073008 };
30083009 }
......@@ -3032,7 +3033,7 @@ pub const Type = struct {
30323033 const union_obj = ip.loadUnionType(union_type);
30333034 return union_obj.field_types.get(ip)[index].toType();
30343035 },
3035 .anon_struct_type => |anon_struct| anon_struct.types[index].toType(),
3036 .anon_struct_type => |anon_struct| anon_struct.types.get(ip)[index].toType(),
30363037 else => unreachable,
30373038 };
30383039 }
......@@ -3046,7 +3047,7 @@ pub const Type = struct {
30463047 return struct_obj.fields.values()[index].alignment(mod, struct_obj.layout);
30473048 },
30483049 .anon_struct_type => |anon_struct| {
3049 return anon_struct.types[index].toType().abiAlignment(mod);
3050 return anon_struct.types.get(ip)[index].toType().abiAlignment(mod);
30503051 },
30513052 .union_type => |union_type| {
30523053 const union_obj = ip.loadUnionType(union_type);
......@@ -3057,7 +3058,8 @@ pub const Type = struct {
30573058 }
30583059
30593060 pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value {
3060 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3061 const ip = &mod.intern_pool;
3062 switch (ip.indexToKey(ty.toIntern())) {
30613063 .struct_type => |struct_type| {
30623064 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
30633065 const val = struct_obj.fields.values()[index].default_val;
......@@ -3066,7 +3068,7 @@ pub const Type = struct {
30663068 return val.toValue();
30673069 },
30683070 .anon_struct_type => |anon_struct| {
3069 const val = anon_struct.values[index];
3071 const val = anon_struct.values.get(ip)[index];
30703072 // TODO: avoid using `unreachable` to indicate this.
30713073 if (val == .none) return Value.@"unreachable";
30723074 return val.toValue();
......@@ -3076,7 +3078,8 @@ pub const Type = struct {
30763078 }
30773079
30783080 pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value {
3079 switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3081 const ip = &mod.intern_pool;
3082 switch (ip.indexToKey(ty.toIntern())) {
30803083 .struct_type => |struct_type| {
30813084 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
30823085 const field = struct_obj.fields.values()[index];
......@@ -3087,9 +3090,9 @@ pub const Type = struct {
30873090 }
30883091 },
30893092 .anon_struct_type => |tuple| {
3090 const val = tuple.values[index];
3093 const val = tuple.values.get(ip)[index];
30913094 if (val == .none) {
3092 return tuple.types[index].toType().onePossibleValue(mod);
3095 return tuple.types.get(ip)[index].toType().onePossibleValue(mod);
30933096 } else {
30943097 return val.toValue();
30953098 }
......@@ -3099,14 +3102,15 @@ pub const Type = struct {
30993102 }
31003103
31013104 pub fn structFieldIsComptime(ty: Type, index: usize, mod: *Module) bool {
3102 return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
3105 const ip = &mod.intern_pool;
3106 return switch (ip.indexToKey(ty.toIntern())) {
31033107 .struct_type => |struct_type| {
31043108 const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
31053109 if (struct_obj.layout == .Packed) return false;
31063110 const field = struct_obj.fields.values()[index];
31073111 return field.is_comptime;
31083112 },
3109 .anon_struct_type => |anon_struct| anon_struct.values[index] != .none,
3113 .anon_struct_type => |anon_struct| anon_struct.values.get(ip)[index] != .none,
31103114 else => unreachable,
31113115 };
31123116 }
......@@ -3202,7 +3206,7 @@ pub const Type = struct {
32023206 var offset: u64 = 0;
32033207 var big_align: u32 = 0;
32043208
3205 for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
3209 for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
32063210 if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) {
32073211 // comptime field
32083212 if (i == index) return offset;
src/value.zig+4-3
......@@ -268,6 +268,7 @@ pub const Value = struct {
268268
269269 pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
270270 if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
271 const ip = &mod.intern_pool;
271272 switch (val.tag()) {
272273 .eu_payload => {
273274 const pl = val.castTag(.eu_payload).?.data;
......@@ -286,7 +287,7 @@ pub const Value = struct {
286287 .slice => {
287288 const pl = val.castTag(.slice).?.data;
288289 const ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod);
289 var ptr_key = mod.intern_pool.indexToKey(ptr).ptr;
290 var ptr_key = ip.indexToKey(ptr).ptr;
290291 assert(ptr_key.len == .none);
291292 ptr_key.ty = ty.toIntern();
292293 ptr_key.len = try pl.len.intern(Type.usize, mod);
......@@ -311,11 +312,11 @@ pub const Value = struct {
311312 const old_elems = val.castTag(.aggregate).?.data[0..len];
312313 const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len);
313314 defer mod.gpa.free(new_elems);
314 const ty_key = mod.intern_pool.indexToKey(ty.toIntern());
315 const ty_key = ip.indexToKey(ty.toIntern());
315316 for (new_elems, old_elems, 0..) |*new_elem, old_elem, field_i|
316317 new_elem.* = try old_elem.intern(switch (ty_key) {
317318 .struct_type => ty.structFieldType(field_i, mod),
318 .anon_struct_type => |info| info.types[field_i].toType(),
319 .anon_struct_type => |info| info.types.get(ip)[field_i].toType(),
319320 inline .array_type, .vector_type => |info| info.child.toType(),
320321 else => unreachable,
321322 }, mod);