aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/InternPool.zig196
-rw-r--r--src/Sema.zig111
-rw-r--r--src/TypedValue.zig7
-rw-r--r--src/codegen.zig6
-rw-r--r--src/codegen/c.zig14
-rw-r--r--src/codegen/llvm.zig25
-rw-r--r--src/codegen/spirv.zig10
-rw-r--r--src/link/Dwarf.zig2
-rw-r--r--src/type.zig48
-rw-r--r--src/value.zig7
10 files changed, 248 insertions, 178 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig
index 3c7c25ffdd..85266954c9 100644
--- a/src/InternPool.zig
+++ b/src/InternPool.zig
@@ -373,11 +373,11 @@ pub const Key = union(enum) {
};
pub const AnonStructType = struct {
- types: []const Index,
+ types: Index.Slice,
/// This may be empty, indicating this is a tuple.
- names: []const NullTerminatedString,
+ names: NullTerminatedString.Slice,
/// These elements may be `none`, indicating runtime-known.
- values: []const Index,
+ values: Index.Slice,
pub fn isTuple(self: AnonStructType) bool {
return self.names.len == 0;
@@ -1020,9 +1020,9 @@ pub const Key = union(enum) {
.anon_struct_type => |anon_struct_type| {
var hasher = Hash.init(seed);
- for (anon_struct_type.types) |elem| std.hash.autoHash(&hasher, elem);
- for (anon_struct_type.values) |elem| std.hash.autoHash(&hasher, elem);
- for (anon_struct_type.names) |elem| std.hash.autoHash(&hasher, elem);
+ for (anon_struct_type.types.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
+ for (anon_struct_type.values.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
+ for (anon_struct_type.names.get(ip)) |elem| std.hash.autoHash(&hasher, elem);
return hasher.final();
},
@@ -1352,9 +1352,9 @@ pub const Key = union(enum) {
},
.anon_struct_type => |a_info| {
const b_info = b.anon_struct_type;
- return std.mem.eql(Index, a_info.types, b_info.types) and
- std.mem.eql(Index, a_info.values, b_info.values) and
- std.mem.eql(NullTerminatedString, a_info.names, b_info.names);
+ return std.mem.eql(Index, a_info.types.get(ip), b_info.types.get(ip)) and
+ std.mem.eql(Index, a_info.values.get(ip), b_info.values.get(ip)) and
+ std.mem.eql(NullTerminatedString, a_info.names.get(ip), b_info.names.get(ip));
},
.error_set_type => |a_info| {
const b_info = b.error_set_type;
@@ -2113,9 +2113,9 @@ pub const static_keys = [_]Key{
// empty_struct_type
.{ .anon_struct_type = .{
- .types = &.{},
- .names = &.{},
- .values = &.{},
+ .types = .{ .start = 0, .len = 0 },
+ .names = .{ .start = 0, .len = 0 },
+ .values = .{ .start = 0, .len = 0 },
} },
.{ .simple_value = .undefined },
@@ -3025,7 +3025,17 @@ pub fn init(ip: *InternPool, gpa: Allocator) !void {
// This inserts all the statically-known values into the intern pool in the
// order expected.
- for (static_keys) |key| _ = ip.get(gpa, key) catch unreachable;
+ for (static_keys[0..@intFromEnum(Index.empty_struct_type)]) |key| {
+ _ = ip.get(gpa, key) catch unreachable;
+ }
+ _ = ip.getAnonStructType(gpa, .{
+ .types = &.{},
+ .names = &.{},
+ .values = &.{},
+ }) catch unreachable;
+ for (static_keys[@intFromEnum(Index.empty_struct_type) + 1 ..]) |key| {
+ _ = ip.get(gpa, key) catch unreachable;
+ }
if (std.debug.runtime_safety) {
// Sanity check.
@@ -3155,30 +3165,8 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
.namespace = @as(Module.Namespace.Index, @enumFromInt(data)).toOptional(),
} },
- .type_struct_anon => {
- const type_struct_anon = ip.extraDataTrail(TypeStructAnon, data);
- const fields_len = type_struct_anon.data.fields_len;
- const types = ip.extra.items[type_struct_anon.end..][0..fields_len];
- const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len];
- const names = ip.extra.items[type_struct_anon.end + 2 * fields_len ..][0..fields_len];
- return .{ .anon_struct_type = .{
- .types = @ptrCast(types),
- .values = @ptrCast(values),
- .names = @ptrCast(names),
- } };
- },
- .type_tuple_anon => {
- const type_struct_anon = ip.extraDataTrail(TypeStructAnon, data);
- const fields_len = type_struct_anon.data.fields_len;
- const types = ip.extra.items[type_struct_anon.end..][0..fields_len];
- const values = ip.extra.items[type_struct_anon.end + fields_len ..][0..fields_len];
- return .{ .anon_struct_type = .{
- .types = @ptrCast(types),
- .values = @ptrCast(values),
- .names = &.{},
- } };
- },
-
+ .type_struct_anon => .{ .anon_struct_type = extraTypeStructAnon(ip, data) },
+ .type_tuple_anon => .{ .anon_struct_type = extraTypeTupleAnon(ip, data) },
.type_union => .{ .union_type = extraUnionType(ip, data) },
.type_enum_auto => {
@@ -3577,6 +3565,44 @@ fn extraUnionType(ip: *const InternPool, extra_index: u32) Key.UnionType {
};
}
+fn extraTypeStructAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {
+ const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);
+ const fields_len = type_struct_anon.data.fields_len;
+ return .{
+ .types = .{
+ .start = type_struct_anon.end,
+ .len = fields_len,
+ },
+ .values = .{
+ .start = type_struct_anon.end + fields_len,
+ .len = fields_len,
+ },
+ .names = .{
+ .start = type_struct_anon.end + fields_len + fields_len,
+ .len = fields_len,
+ },
+ };
+}
+
+fn extraTypeTupleAnon(ip: *const InternPool, extra_index: u32) Key.AnonStructType {
+ const type_struct_anon = ip.extraDataTrail(TypeStructAnon, extra_index);
+ const fields_len = type_struct_anon.data.fields_len;
+ return .{
+ .types = .{
+ .start = type_struct_anon.end,
+ .len = fields_len,
+ },
+ .values = .{
+ .start = type_struct_anon.end + fields_len,
+ .len = fields_len,
+ },
+ .names = .{
+ .start = 0,
+ .len = 0,
+ },
+ };
+}
+
fn extraFuncType(ip: *const InternPool, extra_index: u32) Key.FuncType {
const type_function = ip.extraDataTrail(Tag.TypeFunction, extra_index);
var index: usize = type_function.end;
@@ -3864,44 +3890,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
});
},
- .anon_struct_type => |anon_struct_type| {
- assert(anon_struct_type.types.len == anon_struct_type.values.len);
- for (anon_struct_type.types) |elem| assert(elem != .none);
-
- const fields_len: u32 = @intCast(anon_struct_type.types.len);
- if (anon_struct_type.names.len == 0) {
- try ip.extra.ensureUnusedCapacity(
- gpa,
- @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 2),
- );
- ip.items.appendAssumeCapacity(.{
- .tag = .type_tuple_anon,
- .data = ip.addExtraAssumeCapacity(TypeStructAnon{
- .fields_len = fields_len,
- }),
- });
- ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.types));
- ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.values));
- return @enumFromInt(ip.items.len - 1);
- }
-
- assert(anon_struct_type.names.len == anon_struct_type.types.len);
-
- try ip.extra.ensureUnusedCapacity(
- gpa,
- @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
- );
- ip.items.appendAssumeCapacity(.{
- .tag = .type_struct_anon,
- .data = ip.addExtraAssumeCapacity(TypeStructAnon{
- .fields_len = fields_len,
- }),
- });
- ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.types));
- ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.values));
- ip.extra.appendSliceAssumeCapacity(@ptrCast(anon_struct_type.names));
- return @enumFromInt(ip.items.len - 1);
- },
+ .anon_struct_type => unreachable, // use getAnonStructType() instead
.union_type => unreachable, // use getUnionType() instead
@@ -4408,7 +4397,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
}
},
.anon_struct_type => |anon_struct_type| {
- for (aggregate.storage.values(), anon_struct_type.types) |elem, ty| {
+ for (aggregate.storage.values(), anon_struct_type.types.get(ip)) |elem, ty| {
assert(ip.typeOf(elem) == ty);
}
},
@@ -4426,7 +4415,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
switch (ty_key) {
.anon_struct_type => |anon_struct_type| opv: {
switch (aggregate.storage) {
- .bytes => |bytes| for (anon_struct_type.values, bytes) |value, byte| {
+ .bytes => |bytes| for (anon_struct_type.values.get(ip), bytes) |value, byte| {
if (value != ip.getIfExists(.{ .int = .{
.ty = .u8_type,
.storage = .{ .u64 = byte },
@@ -4434,10 +4423,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
},
.elems => |elems| if (!std.mem.eql(
Index,
- anon_struct_type.values,
+ anon_struct_type.values.get(ip),
elems,
)) break :opv,
- .repeated_elem => |elem| for (anon_struct_type.values) |value| {
+ .repeated_elem => |elem| for (anon_struct_type.values.get(ip)) |value| {
if (value != elem) break :opv;
},
}
@@ -4646,6 +4635,53 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
return @enumFromInt(ip.items.len - 1);
}
+pub const AnonStructTypeInit = struct {
+ types: []const Index,
+ /// This may be empty, indicating this is a tuple.
+ names: []const NullTerminatedString,
+ /// These elements may be `none`, indicating runtime-known.
+ values: []const Index,
+};
+
+pub fn getAnonStructType(ip: *InternPool, gpa: Allocator, ini: AnonStructTypeInit) Allocator.Error!Index {
+ assert(ini.types.len == ini.values.len);
+ for (ini.types) |elem| assert(elem != .none);
+
+ const prev_extra_len = ip.extra.items.len;
+ const fields_len: u32 = @intCast(ini.types.len);
+
+ try ip.extra.ensureUnusedCapacity(
+ gpa,
+ @typeInfo(TypeStructAnon).Struct.fields.len + (fields_len * 3),
+ );
+ try ip.items.ensureUnusedCapacity(gpa, 1);
+
+ const extra_index = ip.addExtraAssumeCapacity(TypeStructAnon{
+ .fields_len = fields_len,
+ });
+ ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.types));
+ ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));
+
+ const adapter: KeyAdapter = .{ .intern_pool = ip };
+ const key: Key = .{
+ .anon_struct_type = if (ini.names.len == 0) extraTypeTupleAnon(ip, extra_index) else k: {
+ assert(ini.names.len == ini.types.len);
+ ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));
+ break :k extraTypeStructAnon(ip, extra_index);
+ },
+ };
+ const gop = try ip.map.getOrPutAdapted(gpa, key, adapter);
+ if (gop.found_existing) {
+ ip.extra.items.len = prev_extra_len;
+ return @enumFromInt(gop.index);
+ }
+ ip.items.appendAssumeCapacity(.{
+ .tag = if (ini.names.len == 0) .type_tuple_anon else .type_struct_anon,
+ .data = extra_index,
+ });
+ return @enumFromInt(ip.items.len - 1);
+}
+
/// This is equivalent to `Key.FuncType` but adjusted to have a slice for `param_types`.
pub const GetFuncTypeKey = struct {
param_types: []Index,
@@ -6056,7 +6092,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
for (agg_elems, 0..) |*elem, i| {
const new_elem_ty = switch (ip.indexToKey(new_ty)) {
inline .array_type, .vector_type => |seq_type| seq_type.child,
- .anon_struct_type => |anon_struct_type| anon_struct_type.types[i],
+ .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[i],
.struct_type => |struct_type| ip.structPtr(struct_type.index.unwrap().?)
.fields.values()[i].ty.toIntern(),
else => unreachable,
diff --git a/src/Sema.zig b/src/Sema.zig
index f7df6b1270..a7a9e99840 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -8052,11 +8052,12 @@ fn instantiateGenericCall(
fn resolveTupleLazyValues(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
const mod = sema.mod;
- const tuple = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ const tuple = switch (ip.indexToKey(ty.toIntern())) {
.anon_struct_type => |tuple| tuple,
else => return,
};
- for (tuple.types, tuple.values) |field_ty, field_val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
try sema.resolveTupleLazyValues(block, src, field_ty.toType());
if (field_val == .none) continue;
// TODO: mutate in intern pool
@@ -12929,7 +12930,7 @@ fn zirHasField(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
},
.anon_struct_type => |anon_struct| {
if (anon_struct.names.len != 0) {
- break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names, field_name) != null;
+ break :hf mem.indexOfScalar(InternPool.NullTerminatedString, anon_struct.names.get(ip), field_name) != null;
} else {
const field_index = field_name.toUnsigned(ip) orelse break :hf false;
break :hf field_index < ty.structFieldCount(mod);
@@ -13558,11 +13559,11 @@ fn analyzeTupleCat(
break :rs runtime_src;
};
- const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
+ const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{
.types = types,
.values = values,
.names = &.{},
- } });
+ });
const runtime_src = opt_runtime_src orelse {
const tuple_val = try mod.intern(.{ .aggregate = .{
@@ -13889,11 +13890,11 @@ fn analyzeTupleMul(
break :rs runtime_src;
};
- const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
+ const tuple_ty = try mod.intern_pool.getAnonStructType(mod.gpa, .{
.types = types,
.values = values,
.names = &.{},
- } });
+ });
const runtime_src = opt_runtime_src orelse {
const tuple_val = try mod.intern(.{ .aggregate = .{
@@ -15217,6 +15218,7 @@ fn zirOverflowArithmetic(
const lhs_ty = sema.typeOf(uncasted_lhs);
const rhs_ty = sema.typeOf(uncasted_rhs);
const mod = sema.mod;
+ const ip = &mod.intern_pool;
try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src);
@@ -15244,7 +15246,7 @@ fn zirOverflowArithmetic(
const maybe_rhs_val = try sema.resolveMaybeUndefVal(rhs);
const tuple_ty = try sema.overflowArithmeticTupleType(dest_ty);
- const overflow_ty = mod.intern_pool.indexToKey(tuple_ty.toIntern()).anon_struct_type.types[1].toType();
+ const overflow_ty = ip.indexToKey(tuple_ty.toIntern()).anon_struct_type.types.get(ip)[1].toType();
var result: struct {
inst: Air.Inst.Ref = .none,
@@ -15418,6 +15420,7 @@ fn splat(sema: *Sema, ty: Type, val: Value) !Value {
fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{
.len = ty.vectorLen(mod),
.child = .u1_type,
@@ -15425,11 +15428,11 @@ fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type {
const types = [2]InternPool.Index{ ty.toIntern(), ov_ty.toIntern() };
const values = [2]InternPool.Index{ .none, .none };
- const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
+ const tuple_ty = try ip.getAnonStructType(mod.gpa, .{
.types = &types,
.values = &values,
.names = &.{},
- } });
+ });
return tuple_ty.toType();
}
@@ -17578,15 +17581,15 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
struct_field_vals = try gpa.alloc(InternPool.Index, tuple.types.len);
for (struct_field_vals, 0..) |*struct_field_val, i| {
const anon_struct_type = ip.indexToKey(ty.toIntern()).anon_struct_type;
- const field_ty = anon_struct_type.types[i];
- const field_val = anon_struct_type.values[i];
+ const field_ty = anon_struct_type.types.get(ip)[i];
+ const field_val = anon_struct_type.values.get(ip)[i];
const name_val = v: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
// TODO: write something like getCoercedInts to avoid needing to dupe
const bytes = if (tuple.names.len != 0)
// https://github.com/ziglang/zig/issues/15709
- try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names[i]))
+ try sema.arena.dupe(u8, ip.stringToSlice(ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip)[i]))
else
try std.fmt.allocPrint(sema.arena, "{d}", .{i});
const new_decl_ty = try mod.arrayType(.{
@@ -19254,7 +19257,7 @@ fn finishStructInit(
switch (ip.indexToKey(struct_ty.toIntern())) {
.anon_struct_type => |anon_struct| {
- for (anon_struct.values, 0..) |default_val, i| {
+ for (anon_struct.values.get(ip), 0..) |default_val, i| {
if (field_inits[i] != .none) continue;
if (default_val == .none) {
@@ -19266,7 +19269,7 @@ fn finishStructInit(
root_msg = try sema.errMsg(block, init_src, template, .{i});
}
} else {
- const field_name = anon_struct.names[i];
+ const field_name = anon_struct.names.get(ip)[i];
const template = "missing struct field: {}";
const args = .{field_name.fmt(ip)};
if (root_msg) |msg| {
@@ -19395,6 +19398,7 @@ fn structInitAnon(
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const zir_datas = sema.code.instructions.items(.data);
const types = try sema.arena.alloc(InternPool.Index, extra_data.fields_len);
@@ -19465,11 +19469,11 @@ fn structInitAnon(
break :rs runtime_index;
};
- const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
+ const tuple_ty = try ip.getAnonStructType(gpa, .{
.names = fields.keys(),
.types = types,
.values = values,
- } });
+ });
const runtime_index = opt_runtime_index orelse {
const tuple_val = try mod.intern(.{ .aggregate = .{
@@ -19688,6 +19692,8 @@ fn arrayInitAnon(
is_ref: bool,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
+ const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const types = try sema.arena.alloc(InternPool.Index, operands.len);
const values = try sema.arena.alloc(InternPool.Index, operands.len);
@@ -19701,7 +19707,7 @@ fn arrayInitAnon(
if (types[i].toType().zigTypeTag(mod) == .Opaque) {
const msg = msg: {
const msg = try sema.errMsg(block, operand_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
- errdefer msg.destroy(sema.gpa);
+ errdefer msg.destroy(gpa);
try sema.addDeclaredHereNote(msg, types[i].toType());
break :msg msg;
@@ -19718,11 +19724,11 @@ fn arrayInitAnon(
break :rs runtime_src;
};
- const tuple_ty = try mod.intern(.{ .anon_struct_type = .{
+ const tuple_ty = try ip.getAnonStructType(gpa, .{
.types = types,
.values = values,
.names = &.{},
- } });
+ });
const runtime_src = opt_runtime_src orelse {
const tuple_val = try mod.intern(.{ .aggregate = .{
@@ -19832,7 +19838,7 @@ fn fieldType(
.Struct => switch (ip.indexToKey(cur_ty.toIntern())) {
.anon_struct_type => |anon_struct| {
const field_index = try sema.anonStructFieldIndex(block, cur_ty, field_name, field_src);
- return Air.internedToRef(anon_struct.types[field_index]);
+ return Air.internedToRef(anon_struct.types.get(ip)[field_index]);
},
.struct_type => |struct_type| {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
@@ -30574,13 +30580,14 @@ fn coerceAnonStructToUnion(
inst_src: LazySrcLoc,
) !Air.Inst.Ref {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const inst_ty = sema.typeOf(inst);
const field_info: union(enum) {
name: InternPool.NullTerminatedString,
count: usize,
- } = switch (mod.intern_pool.indexToKey(inst_ty.toIntern())) {
+ } = switch (ip.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len == 1)
- .{ .name = anon_struct_type.names[0] }
+ .{ .name = anon_struct_type.names.get(ip)[0] }
else
.{ .count = anon_struct_type.names.len },
.struct_type => |struct_type| name: {
@@ -30876,7 +30883,7 @@ fn coerceTupleToStruct(
// https://github.com/ziglang/zig/issues/15709
const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
- anon_struct_type.names[field_i]
+ anon_struct_type.names.get(ip)[field_i]
else
try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
@@ -30994,7 +31001,7 @@ fn coerceTupleToTuple(
// https://github.com/ziglang/zig/issues/15709
const field_name: InternPool.NullTerminatedString = switch (ip.indexToKey(inst_ty.toIntern())) {
.anon_struct_type => |anon_struct_type| if (anon_struct_type.names.len > 0)
- anon_struct_type.names[field_i]
+ anon_struct_type.names.get(ip)[field_i]
else
try ip.getOrPutStringFmt(sema.gpa, "{d}", .{field_i}),
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.keys()[field_i],
@@ -31005,12 +31012,12 @@ fn coerceTupleToTuple(
return sema.fail(block, field_src, "cannot assign to 'len' field of tuple", .{});
const field_ty = switch (ip.indexToKey(tuple_ty.toIntern())) {
- .anon_struct_type => |anon_struct_type| anon_struct_type.types[field_index_usize].toType(),
+ .anon_struct_type => |anon_struct_type| anon_struct_type.types.get(ip)[field_index_usize].toType(),
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].ty,
else => unreachable,
};
const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
- .anon_struct_type => |anon_struct_type| anon_struct_type.values[field_index_usize],
+ .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[field_index_usize],
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[field_index_usize].default_val,
else => unreachable,
};
@@ -31048,7 +31055,7 @@ fn coerceTupleToTuple(
if (field_ref.* != .none) continue;
const default_val = switch (ip.indexToKey(tuple_ty.toIntern())) {
- .anon_struct_type => |anon_struct_type| anon_struct_type.values[i],
+ .anon_struct_type => |anon_struct_type| anon_struct_type.values.get(ip)[i],
.struct_type => |struct_type| mod.structPtrUnwrap(struct_type.index).?.fields.values()[i].default_val,
else => unreachable,
};
@@ -32855,6 +32862,7 @@ fn resolvePeerTypesInner(
peer_vals: []?Value,
) !PeerResolveResult {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
var strat_reason: usize = 0;
var s: PeerResolveStrategy = .unknown;
@@ -32912,7 +32920,7 @@ fn resolvePeerTypesInner(
.ErrorUnion => blk: {
const set_ty = ty.errorUnionSet(mod);
ty_ptr.* = ty.errorUnionPayload(mod);
- if (val_ptr.*) |eu_val| switch (mod.intern_pool.indexToKey(eu_val.toIntern())) {
+ if (val_ptr.*) |eu_val| switch (ip.indexToKey(eu_val.toIntern())) {
.error_union => |eu| switch (eu.val) {
.payload => |payload_ip| val_ptr.* = payload_ip.toValue(),
.err_name => val_ptr.* = null,
@@ -33166,8 +33174,8 @@ fn resolvePeerTypesInner(
}).toIntern();
if (ptr_info.sentinel != .none and peer_info.sentinel != .none) {
- const peer_sent = try mod.intern_pool.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);
- const ptr_sent = try mod.intern_pool.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);
+ const peer_sent = try ip.getCoerced(sema.gpa, ptr_info.sentinel, ptr_info.child);
+ const ptr_sent = try ip.getCoerced(sema.gpa, peer_info.sentinel, ptr_info.child);
if (ptr_sent == peer_sent) {
ptr_info.sentinel = ptr_sent;
} else {
@@ -33278,7 +33286,7 @@ fn resolvePeerTypesInner(
ptr_info.flags.is_volatile = ptr_info.flags.is_volatile or peer_info.flags.is_volatile;
const peer_sentinel: InternPool.Index = switch (peer_info.flags.size) {
- .One => switch (mod.intern_pool.indexToKey(peer_info.child)) {
+ .One => switch (ip.indexToKey(peer_info.child)) {
.array_type => |array_type| array_type.sentinel,
else => .none,
},
@@ -33287,7 +33295,7 @@ fn resolvePeerTypesInner(
};
const cur_sentinel: InternPool.Index = switch (ptr_info.flags.size) {
- .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
+ .One => switch (ip.indexToKey(ptr_info.child)) {
.array_type => |array_type| array_type.sentinel,
else => .none,
},
@@ -33449,7 +33457,7 @@ fn resolvePeerTypesInner(
}
const sentinel_ty = switch (ptr_info.flags.size) {
- .One => switch (mod.intern_pool.indexToKey(ptr_info.child)) {
+ .One => switch (ip.indexToKey(ptr_info.child)) {
.array_type => |array_type| array_type.child,
else => ptr_info.child,
},
@@ -33460,11 +33468,11 @@ fn resolvePeerTypesInner(
no_sentinel: {
if (peer_sentinel == .none) break :no_sentinel;
if (cur_sentinel == .none) break :no_sentinel;
- const peer_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);
- const cur_sent_coerced = try mod.intern_pool.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);
+ const peer_sent_coerced = try ip.getCoerced(sema.gpa, peer_sentinel, sentinel_ty);
+ const cur_sent_coerced = try ip.getCoerced(sema.gpa, cur_sentinel, sentinel_ty);
if (peer_sent_coerced != cur_sent_coerced) break :no_sentinel;
// Sentinels match
- if (ptr_info.flags.size == .One) switch (mod.intern_pool.indexToKey(ptr_info.child)) {
+ if (ptr_info.flags.size == .One) switch (ip.indexToKey(ptr_info.child)) {
.array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
.len = array_type.len,
.child = array_type.child,
@@ -33478,7 +33486,7 @@ fn resolvePeerTypesInner(
}
// Clear existing sentinel
ptr_info.sentinel = .none;
- switch (mod.intern_pool.indexToKey(ptr_info.child)) {
+ switch (ip.indexToKey(ptr_info.child)) {
.array_type => |array_type| ptr_info.child = (try mod.arrayType(.{
.len = array_type.len,
.child = array_type.child,
@@ -33501,7 +33509,7 @@ fn resolvePeerTypesInner(
.peer_idx_a = first_idx,
.peer_idx_b = other_idx,
} },
- else => switch (mod.intern_pool.indexToKey(pointee)) {
+ else => switch (ip.indexToKey(pointee)) {
.array_type => |array_type| if (array_type.child == .noreturn_type) return .{ .conflict = .{
.peer_idx_a = first_idx,
.peer_idx_b = other_idx,
@@ -33785,7 +33793,7 @@ fn resolvePeerTypesInner(
is_tuple = ty.isTuple(mod);
field_count = ty.structFieldCount(mod);
if (!is_tuple) {
- const names = mod.intern_pool.indexToKey(ty.toIntern()).anon_struct_type.names;
+ const names = ip.indexToKey(ty.toIntern()).anon_struct_type.names.get(ip);
field_names = try sema.arena.dupe(InternPool.NullTerminatedString, names);
}
continue;
@@ -33839,7 +33847,7 @@ fn resolvePeerTypesInner(
result_buf.* = result;
const field_name = if (is_tuple) name: {
break :name try std.fmt.allocPrint(sema.arena, "{d}", .{field_idx});
- } else try sema.arena.dupe(u8, mod.intern_pool.stringToSlice(field_names[field_idx]));
+ } else try sema.arena.dupe(u8, ip.stringToSlice(field_names[field_idx]));
// The error info needs the field types, but we can't reuse sub_peer_tys
// since the recursive call may have clobbered it.
@@ -33892,11 +33900,11 @@ fn resolvePeerTypesInner(
field_val.* = if (comptime_val) |v| v.toIntern() else .none;
}
- const final_ty = try mod.intern(.{ .anon_struct_type = .{
+ const final_ty = try ip.getAnonStructType(mod.gpa, .{
.types = field_types,
.names = if (is_tuple) &.{} else field_names,
.values = field_vals,
- } });
+ });
return .{ .success = final_ty.toType() };
},
@@ -34491,6 +34499,7 @@ fn resolveUnionLayout(sema: *Sema, ty: Type) CompileError!void {
/// be resolved.
pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
switch (ty.zigTypeTag(mod)) {
.Pointer => {
return sema.resolveTypeFully(ty.childType(mod));
@@ -34498,7 +34507,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
.Struct => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
.struct_type => return sema.resolveStructFully(ty),
.anon_struct_type => |tuple| {
- for (tuple.types) |field_ty| {
+ for (tuple.types.get(ip)) |field_ty| {
try sema.resolveTypeFully(field_ty.toType());
}
},
@@ -34518,7 +34527,6 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void {
// the function is instantiated.
return;
}
- const ip = &mod.intern_pool;
for (0..info.param_types.len) |i| {
const param_ty = info.param_types.get(ip)[i];
try sema.resolveTypeFully(param_ty.toType());
@@ -36133,7 +36141,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
},
.anon_struct_type => |tuple| {
- for (tuple.values) |val| {
+ for (tuple.values.get(ip)) |val| {
if (val == .none) return null;
}
// In this case the struct has all comptime-known fields and
@@ -36141,7 +36149,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
// TODO: write something like getCoercedInts to avoid needing to dupe
return (try mod.intern(.{ .aggregate = .{
.ty = ty.toIntern(),
- .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values) },
+ .storage = .{ .elems = try sema.arena.dupe(InternPool.Index, tuple.values.get(ip)) },
} })).toValue();
},
@@ -36611,7 +36619,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
}
},
.anon_struct_type => |tuple| {
- for (tuple.types, tuple.values) |field_ty, val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
const have_comptime_val = val != .none;
if (!have_comptime_val and try sema.typeRequiresComptime(field_ty.toType())) {
return true;
@@ -36784,8 +36792,9 @@ fn anonStructFieldIndex(
field_src: LazySrcLoc,
) !u32 {
const mod = sema.mod;
- switch (mod.intern_pool.indexToKey(struct_ty.toIntern())) {
- .anon_struct_type => |anon_struct_type| for (anon_struct_type.names, 0..) |name, i| {
+ const ip = &mod.intern_pool;
+ switch (ip.indexToKey(struct_ty.toIntern())) {
+ .anon_struct_type => |anon_struct_type| for (anon_struct_type.names.get(ip), 0..) |name, i| {
if (name == field_name) return @intCast(i);
},
.struct_type => |struct_type| if (mod.structPtrUnwrap(struct_type.index)) |struct_obj| {
@@ -36798,7 +36807,7 @@ fn anonStructFieldIndex(
else => unreachable,
}
return sema.fail(block, field_src, "no field named '{}' in anonymous struct '{}'", .{
- field_name.fmt(&mod.intern_pool), struct_ty.fmt(sema.mod),
+ field_name.fmt(ip), struct_ty.fmt(sema.mod),
});
}
diff --git a/src/TypedValue.zig b/src/TypedValue.zig
index 950613f4ff..659f70a10c 100644
--- a/src/TypedValue.zig
+++ b/src/TypedValue.zig
@@ -423,6 +423,7 @@ fn printAggregate(
if (level == 0) {
return writer.writeAll(".{ ... }");
}
+ const ip = &mod.intern_pool;
if (ty.zigTypeTag(mod) == .Struct) {
try writer.writeAll(".{");
const max_len = @min(ty.structFieldCount(mod), max_aggregate_items);
@@ -430,13 +431,13 @@ fn printAggregate(
for (0..max_len) |i| {
if (i != 0) try writer.writeAll(", ");
- const field_name = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const field_name = switch (ip.indexToKey(ty.toIntern())) {
.struct_type => |x| mod.structPtrUnwrap(x.index).?.fields.keys()[i].toOptional(),
- .anon_struct_type => |x| if (x.isTuple()) .none else x.names[i].toOptional(),
+ .anon_struct_type => |x| if (x.isTuple()) .none else x.names.get(ip)[i].toOptional(),
else => unreachable,
};
- if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(&mod.intern_pool)});
+ if (field_name.unwrap()) |name| try writer.print(".{} = ", .{name.fmt(ip)});
try print(.{
.ty = ty.structFieldType(i, mod),
.val = try val.fieldValue(mod, i),
diff --git a/src/codegen.zig b/src/codegen.zig
index 3a802f4d86..4d1993434a 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -438,7 +438,11 @@ pub fn generateSymbol(
},
.anon_struct_type => |tuple| {
const struct_begin = code.items.len;
- for (tuple.types, tuple.values, 0..) |field_ty, comptime_val, index| {
+ for (
+ tuple.types.get(ip),
+ tuple.values.get(ip),
+ 0..,
+ ) |field_ty, comptime_val, index| {
if (comptime_val != .none) continue;
if (!field_ty.toType().hasRuntimeBits(mod)) continue;
diff --git a/src/codegen/c.zig b/src/codegen/c.zig
index 2ac9188704..ed27d94130 100644
--- a/src/codegen/c.zig
+++ b/src/codegen/c.zig
@@ -1275,7 +1275,11 @@ pub const DeclGen = struct {
try writer.writeByte('{');
var empty = true;
- for (tuple.types, tuple.values, 0..) |field_ty, comptime_ty, field_i| {
+ for (
+ tuple.types.get(ip),
+ tuple.values.get(ip),
+ 0..,
+ ) |field_ty, comptime_ty, field_i| {
if (comptime_ty != .none) continue;
if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
@@ -7745,16 +7749,18 @@ fn lowerFnRetTy(ret_ty: Type, mod: *Module) !Type {
if (ret_ty.ip_index == .noreturn_type) return Type.noreturn;
if (lowersToArray(ret_ty, mod)) {
+ const gpa = mod.gpa;
+ const ip = &mod.intern_pool;
const names = [1]InternPool.NullTerminatedString{
- try mod.intern_pool.getOrPutString(mod.gpa, "array"),
+ try ip.getOrPutString(gpa, "array"),
};
const types = [1]InternPool.Index{ret_ty.ip_index};
const values = [1]InternPool.Index{.none};
- const interned = try mod.intern(.{ .anon_struct_type = .{
+ const interned = try ip.getAnonStructType(gpa, .{
.names = &names,
.types = &types,
.values = &values,
- } });
+ });
return interned.toType();
}
diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig
index a2ded0cc8d..7a46472c62 100644
--- a/src/codegen/llvm.zig
+++ b/src/codegen/llvm.zig
@@ -2392,7 +2392,7 @@ pub const Object = struct {
comptime assert(struct_layout_version == 2);
var offset: u64 = 0;
- for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
+ for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
const field_size = field_ty.toType().abiSize(mod);
@@ -2401,7 +2401,7 @@ pub const Object = struct {
offset = field_offset + field_size;
const field_name = if (tuple.names.len != 0)
- ip.stringToSlice(tuple.names[i])
+ ip.stringToSlice(tuple.names.get(ip)[i])
else
try std.fmt.allocPrintZ(gpa, "{d}", .{i});
defer if (tuple.names.len == 0) gpa.free(field_name);
@@ -3325,7 +3325,10 @@ pub const Object = struct {
var offset: u64 = 0;
var big_align: u32 = 0;
- for (anon_struct_type.types, anon_struct_type.values) |field_ty, field_val| {
+ for (
+ anon_struct_type.types.get(ip),
+ anon_struct_type.values.get(ip),
+ ) |field_ty, field_val| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
const field_align = field_ty.toType().abiAlignment(mod);
@@ -3874,7 +3877,11 @@ pub const Object = struct {
var offset: u64 = 0;
var big_align: u32 = 0;
var need_unnamed = false;
- for (tuple.types, tuple.values, 0..) |field_ty, field_val, field_index| {
+ for (
+ tuple.types.get(ip),
+ tuple.values.get(ip),
+ 0..,
+ ) |field_ty, field_val, field_index| {
if (field_val != .none) continue;
if (!field_ty.toType().hasRuntimeBitsIgnoreComptime(mod)) continue;
@@ -10537,10 +10544,11 @@ fn llvmField(ty: Type, field_index: usize, mod: *Module) ?LlvmField {
var offset: u64 = 0;
var big_align: u32 = 0;
- const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ const struct_type = switch (ip.indexToKey(ty.toIntern())) {
.anon_struct_type => |tuple| {
var llvm_field_index: c_uint = 0;
- for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
+ for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
const field_align = field_ty.toType().abiAlignment(mod);
@@ -11118,6 +11126,7 @@ fn isByRef(ty: Type, mod: *Module) bool {
// For tuples and structs, if there are more than this many non-void
// fields, then we make it byref, otherwise byval.
const max_fields_byval = 0;
+ const ip = &mod.intern_pool;
switch (ty.zigTypeTag(mod)) {
.Type,
@@ -11146,10 +11155,10 @@ fn isByRef(ty: Type, mod: *Module) bool {
.Struct => {
// Packed structs are represented to LLVM as integers.
if (ty.containerLayout(mod) == .Packed) return false;
- const struct_type = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const struct_type = switch (ip.indexToKey(ty.toIntern())) {
.anon_struct_type => |tuple| {
var count: usize = 0;
- for (tuple.types, tuple.values) |field_ty, field_val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
count += 1;
diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig
index b44b09307b..b4d996528b 100644
--- a/src/codegen/spirv.zig
+++ b/src/codegen/spirv.zig
@@ -1227,6 +1227,7 @@ pub const DeclGen = struct {
/// Turn a Zig type into a SPIR-V Type, and return a reference to it.
fn resolveType(self: *DeclGen, ty: Type, repr: Repr) Error!CacheRef {
const mod = self.module;
+ const ip = &mod.intern_pool;
log.debug("resolveType: ty = {}", .{ty.fmt(self.module)});
const target = self.getTarget();
switch (ty.zigTypeTag(mod)) {
@@ -1271,7 +1272,6 @@ pub const DeclGen = struct {
},
.Fn => switch (repr) {
.direct => {
- const ip = &mod.intern_pool;
const fn_info = mod.typeToFunc(ty).?;
// TODO: Put this somewhere in Sema.zig
if (fn_info.is_var_args)
@@ -1333,13 +1333,13 @@ pub const DeclGen = struct {
} });
},
.Struct => {
- const struct_ty = switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const struct_ty = switch (ip.indexToKey(ty.toIntern())) {
.anon_struct_type => |tuple| {
const member_types = try self.gpa.alloc(CacheRef, tuple.values.len);
defer self.gpa.free(member_types);
var member_index: usize = 0;
- for (tuple.types, tuple.values) |field_ty, field_val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, field_val| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) continue;
member_types[member_index] = try self.resolveType(field_ty.toType(), .indirect);
@@ -1369,12 +1369,12 @@ pub const DeclGen = struct {
while (it.next()) |field_and_index| {
const field = field_and_index.field;
const index = field_and_index.index;
- const field_name = mod.intern_pool.stringToSlice(struct_obj.fields.keys()[index]);
+ const field_name = ip.stringToSlice(struct_obj.fields.keys()[index]);
try member_types.append(try self.resolveType(field.ty, .indirect));
try member_names.append(try self.spv.resolveString(field_name));
}
- const name = mod.intern_pool.stringToSlice(try struct_obj.getFullyQualifiedName(self.module));
+ const name = ip.stringToSlice(try struct_obj.getFullyQualifiedName(self.module));
return try self.spv.resolve(.{ .struct_type = .{
.name = try self.spv.resolveString(name),
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
index 252388cc8b..48c828e54a 100644
--- a/src/link/Dwarf.zig
+++ b/src/link/Dwarf.zig
@@ -327,7 +327,7 @@ pub const DeclState = struct {
// DW.AT.name, DW.FORM.string
try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
- for (fields.types, 0..) |field_ty, field_index| {
+ for (fields.types.get(ip), 0..) |field_ty, field_index| {
// DW.AT.member
try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
diff --git a/src/type.zig b/src/type.zig
index 8d4d9edf86..67f855806f 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -170,7 +170,8 @@ pub const Type = struct {
/// Prints a name suitable for `@typeName`.
pub fn print(ty: Type, writer: anytype, mod: *Module) @TypeOf(writer).Error!void {
- switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ switch (ip.indexToKey(ty.toIntern())) {
.int_type => |int_type| {
const sign_char: u8 = switch (int_type.signedness) {
.signed => 'i',
@@ -257,7 +258,6 @@ pub const Type = struct {
try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");
},
.error_set_type => |error_set_type| {
- const ip = &mod.intern_pool;
const names = error_set_type.names;
try writer.writeAll("error{");
for (names.get(ip), 0..) |name, i| {
@@ -330,13 +330,13 @@ pub const Type = struct {
return writer.writeAll("@TypeOf(.{})");
}
try writer.writeAll("struct{");
- for (anon_struct.types, anon_struct.values, 0..) |field_ty, val, i| {
+ for (anon_struct.types.get(ip), anon_struct.values.get(ip), 0..) |field_ty, val, i| {
if (i != 0) try writer.writeAll(", ");
if (val != .none) {
try writer.writeAll("comptime ");
}
if (anon_struct.names.len != 0) {
- try writer.print("{}: ", .{anon_struct.names[i].fmt(&mod.intern_pool)});
+ try writer.print("{}: ", .{anon_struct.names.get(ip)[i].fmt(&mod.intern_pool)});
}
try print(field_ty.toType(), writer, mod);
@@ -587,7 +587,7 @@ pub const Type = struct {
}
},
.anon_struct_type => |tuple| {
- for (tuple.types, tuple.values) |field_ty, val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
if (val != .none) continue; // comptime field
if (try field_ty.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat)) return true;
}
@@ -1055,7 +1055,7 @@ pub const Type = struct {
},
.anon_struct_type => |tuple| {
var big_align: u32 = 0;
- for (tuple.types, tuple.values) |field_ty, val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
if (val != .none) continue; // comptime field
if (!(field_ty.toType().hasRuntimeBits(mod))) continue;
@@ -2155,7 +2155,7 @@ pub const Type = struct {
pub fn vectorLen(ty: Type, mod: *const Module) u32 {
return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
.vector_type => |vector_type| vector_type.len,
- .anon_struct_type => |tuple| @as(u32, @intCast(tuple.types.len)),
+ .anon_struct_type => |tuple| @intCast(tuple.types.len),
else => unreachable,
};
}
@@ -2536,13 +2536,13 @@ pub const Type = struct {
},
.anon_struct_type => |tuple| {
- for (tuple.values) |val| {
+ for (tuple.values.get(ip)) |val| {
if (val == .none) return null;
}
// In this case the struct has all comptime-known fields and
// therefore has one possible value.
// TODO: write something like getCoercedInts to avoid needing to dupe
- const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values);
+ const duped_values = try mod.gpa.dupe(InternPool.Index, tuple.values.get(ip));
defer mod.gpa.free(duped_values);
return (try mod.intern(.{ .aggregate = .{
.ty = ty.toIntern(),
@@ -2732,7 +2732,7 @@ pub const Type = struct {
},
.anon_struct_type => |tuple| {
- for (tuple.types, tuple.values) |field_ty, val| {
+ for (tuple.types.get(ip), tuple.values.get(ip)) |field_ty, val| {
const have_comptime_val = val != .none;
if (!have_comptime_val and field_ty.toType().comptimeOnly(mod)) return true;
}
@@ -2996,13 +2996,14 @@ pub const Type = struct {
}
pub fn structFieldName(ty: Type, field_index: usize, mod: *Module) InternPool.NullTerminatedString {
- return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ return switch (ip.indexToKey(ty.toIntern())) {
.struct_type => |struct_type| {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
assert(struct_obj.haveFieldTypes());
return struct_obj.fields.keys()[field_index];
},
- .anon_struct_type => |anon_struct| anon_struct.names[field_index],
+ .anon_struct_type => |anon_struct| anon_struct.names.get(ip)[field_index],
else => unreachable,
};
}
@@ -3032,7 +3033,7 @@ pub const Type = struct {
const union_obj = ip.loadUnionType(union_type);
return union_obj.field_types.get(ip)[index].toType();
},
- .anon_struct_type => |anon_struct| anon_struct.types[index].toType(),
+ .anon_struct_type => |anon_struct| anon_struct.types.get(ip)[index].toType(),
else => unreachable,
};
}
@@ -3046,7 +3047,7 @@ pub const Type = struct {
return struct_obj.fields.values()[index].alignment(mod, struct_obj.layout);
},
.anon_struct_type => |anon_struct| {
- return anon_struct.types[index].toType().abiAlignment(mod);
+ return anon_struct.types.get(ip)[index].toType().abiAlignment(mod);
},
.union_type => |union_type| {
const union_obj = ip.loadUnionType(union_type);
@@ -3057,7 +3058,8 @@ pub const Type = struct {
}
pub fn structFieldDefaultValue(ty: Type, index: usize, mod: *Module) Value {
- switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ switch (ip.indexToKey(ty.toIntern())) {
.struct_type => |struct_type| {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
const val = struct_obj.fields.values()[index].default_val;
@@ -3066,7 +3068,7 @@ pub const Type = struct {
return val.toValue();
},
.anon_struct_type => |anon_struct| {
- const val = anon_struct.values[index];
+ const val = anon_struct.values.get(ip)[index];
// TODO: avoid using `unreachable` to indicate this.
if (val == .none) return Value.@"unreachable";
return val.toValue();
@@ -3076,7 +3078,8 @@ pub const Type = struct {
}
pub fn structFieldValueComptime(ty: Type, mod: *Module, index: usize) !?Value {
- switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ switch (ip.indexToKey(ty.toIntern())) {
.struct_type => |struct_type| {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
const field = struct_obj.fields.values()[index];
@@ -3087,9 +3090,9 @@ pub const Type = struct {
}
},
.anon_struct_type => |tuple| {
- const val = tuple.values[index];
+ const val = tuple.values.get(ip)[index];
if (val == .none) {
- return tuple.types[index].toType().onePossibleValue(mod);
+ return tuple.types.get(ip)[index].toType().onePossibleValue(mod);
} else {
return val.toValue();
}
@@ -3099,14 +3102,15 @@ pub const Type = struct {
}
pub fn structFieldIsComptime(ty: Type, index: usize, mod: *Module) bool {
- return switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ const ip = &mod.intern_pool;
+ return switch (ip.indexToKey(ty.toIntern())) {
.struct_type => |struct_type| {
const struct_obj = mod.structPtrUnwrap(struct_type.index).?;
if (struct_obj.layout == .Packed) return false;
const field = struct_obj.fields.values()[index];
return field.is_comptime;
},
- .anon_struct_type => |anon_struct| anon_struct.values[index] != .none,
+ .anon_struct_type => |anon_struct| anon_struct.values.get(ip)[index] != .none,
else => unreachable,
};
}
@@ -3202,7 +3206,7 @@ pub const Type = struct {
var offset: u64 = 0;
var big_align: u32 = 0;
- for (tuple.types, tuple.values, 0..) |field_ty, field_val, i| {
+ for (tuple.types.get(ip), tuple.values.get(ip), 0..) |field_ty, field_val, i| {
if (field_val != .none or !field_ty.toType().hasRuntimeBits(mod)) {
// comptime field
if (i == index) return offset;
diff --git a/src/value.zig b/src/value.zig
index 848da16cf8..13eb9106b5 100644
--- a/src/value.zig
+++ b/src/value.zig
@@ -268,6 +268,7 @@ pub const Value = struct {
pub fn intern(val: Value, ty: Type, mod: *Module) Allocator.Error!InternPool.Index {
if (val.ip_index != .none) return (try mod.getCoerced(val, ty)).toIntern();
+ const ip = &mod.intern_pool;
switch (val.tag()) {
.eu_payload => {
const pl = val.castTag(.eu_payload).?.data;
@@ -286,7 +287,7 @@ pub const Value = struct {
.slice => {
const pl = val.castTag(.slice).?.data;
const ptr = try pl.ptr.intern(ty.slicePtrFieldType(mod), mod);
- var ptr_key = mod.intern_pool.indexToKey(ptr).ptr;
+ var ptr_key = ip.indexToKey(ptr).ptr;
assert(ptr_key.len == .none);
ptr_key.ty = ty.toIntern();
ptr_key.len = try pl.len.intern(Type.usize, mod);
@@ -311,11 +312,11 @@ pub const Value = struct {
const old_elems = val.castTag(.aggregate).?.data[0..len];
const new_elems = try mod.gpa.alloc(InternPool.Index, old_elems.len);
defer mod.gpa.free(new_elems);
- const ty_key = mod.intern_pool.indexToKey(ty.toIntern());
+ const ty_key = ip.indexToKey(ty.toIntern());
for (new_elems, old_elems, 0..) |*new_elem, old_elem, field_i|
new_elem.* = try old_elem.intern(switch (ty_key) {
.struct_type => ty.structFieldType(field_i, mod),
- .anon_struct_type => |info| info.types[field_i].toType(),
+ .anon_struct_type => |info| info.types.get(ip)[field_i].toType(),
inline .array_type, .vector_type => |info| info.child.toType(),
else => unreachable,
}, mod);