aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2023-08-17 14:25:18 -0700
committerAndrew Kelley <andrew@ziglang.org>2023-08-17 18:16:03 -0700
commit7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b (patch)
tree6a76839d8be347648741e17f50d6c70d8313adc3 /src/Sema.zig
parent8c1329b222ab620d7388d766e9e558baa502ce93 (diff)
downloadzig-7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b.tar.gz
zig-7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b.zip
InternPool: safer enum API
The key changes in this commit are: ```diff - names: []const NullTerminatedString, + names: NullTerminatedString.Slice, - values: []const Index, + values: Index.Slice, ``` Which eliminates the slices from `InternPool.Key.EnumType` and replaces them with structs that contain `start` and `len` indexes. This makes the lifetime of `EnumType` change from expiring with updates to InternPool, to expiring when the InternPool is garbage-collected, which is currently never. This is gearing up for a larger change I started working on locally which moves union types into InternPool. As a bonus, I fixed some unnecessary instances of `@as`.
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig31
1 files changed, 17 insertions, 14 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 396ef9a786..d62cf3ef0c 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -17170,14 +17170,14 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
for (enum_field_vals, 0..) |*field_val, i| {
const enum_type = ip.indexToKey(ty.toIntern()).enum_type;
const value_val = if (enum_type.values.len > 0)
- try mod.intern_pool.getCoerced(gpa, enum_type.values[i], .comptime_int_type)
+ try mod.intern_pool.getCoerced(gpa, enum_type.values.get(ip)[i], .comptime_int_type)
else
try mod.intern(.{ .int = .{
.ty = .comptime_int_type,
.storage = .{ .u64 = @as(u64, @intCast(i)) },
} });
// TODO: write something like getCoercedInts to avoid needing to dupe
- const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names[i]));
+ const name = try sema.arena.dupe(u8, ip.stringToSlice(enum_type.names.get(ip)[i]));
const name_val = v: {
var anon_decl = try block.startAnonDecl();
defer anon_decl.deinit();
@@ -20601,7 +20601,7 @@ fn zirReify(
errdefer msg.destroy(gpa);
const enum_ty = union_obj.tag_ty;
- for (tag_info.names, 0..) |field_name, field_index| {
+ for (tag_info.names.get(ip), 0..) |field_name, field_index| {
if (explicit_tags_seen[field_index]) continue;
try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{}' missing, declared here", .{
field_name.fmt(ip),
@@ -35420,7 +35420,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
errdefer msg.destroy(sema.gpa);
const enum_ty = union_obj.tag_ty;
- for (tag_info.names, 0..) |field_name, field_index| {
+ for (tag_info.names.get(ip), 0..) |field_name, field_index| {
if (explicit_tags_seen[field_index]) continue;
try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{}' missing, declared here", .{
field_name.fmt(ip),
@@ -35452,12 +35452,13 @@ fn generateUnionTagTypeNumbered(
) !Type {
const mod = sema.mod;
const gpa = sema.gpa;
+ const ip = &mod.intern_pool;
const src_decl = mod.declPtr(block.src_decl);
const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
errdefer mod.destroyDecl(new_decl_index);
const fqn = try union_obj.getFullyQualifiedName(mod);
- const name = try mod.intern_pool.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(&mod.intern_pool)});
+ const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{
.ty = Type.noreturn,
.val = Value.@"unreachable",
@@ -35469,17 +35470,17 @@ fn generateUnionTagTypeNumbered(
new_decl.owns_tv = true;
new_decl.name_fully_qualified = true;
- const enum_ty = try mod.intern(.{ .enum_type = .{
+ const enum_ty = try ip.getEnum(gpa, .{
.decl = new_decl_index,
.namespace = .none,
.tag_ty = if (enum_field_vals.len == 0)
(try mod.intType(.unsigned, 0)).toIntern()
else
- mod.intern_pool.typeOf(enum_field_vals[0]),
+ ip.typeOf(enum_field_vals[0]),
.names = enum_field_names,
.values = enum_field_vals,
.tag_mode = .explicit,
- } });
+ });
new_decl.ty = Type.type;
new_decl.val = enum_ty.toValue();
@@ -35495,6 +35496,7 @@ fn generateUnionTagTypeSimple(
maybe_union_obj: ?*Module.Union,
) !Type {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
const gpa = sema.gpa;
const new_decl_index = new_decl_index: {
@@ -35508,7 +35510,7 @@ fn generateUnionTagTypeSimple(
const new_decl_index = try mod.allocateNewDecl(block.namespace, src_decl.src_node, block.wip_capture_scope);
errdefer mod.destroyDecl(new_decl_index);
const fqn = try union_obj.getFullyQualifiedName(mod);
- const name = try mod.intern_pool.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(&mod.intern_pool)});
+ const name = try ip.getOrPutStringFmt(gpa, "@typeInfo({}).Union.tag_type.?", .{fqn.fmt(ip)});
try mod.initNewAnonDecl(new_decl_index, src_decl.src_line, .{
.ty = Type.noreturn,
.val = Value.@"unreachable",
@@ -35518,7 +35520,7 @@ fn generateUnionTagTypeSimple(
};
errdefer mod.abortAnonDecl(new_decl_index);
- const enum_ty = try mod.intern(.{ .enum_type = .{
+ const enum_ty = try ip.getEnum(gpa, .{
.decl = new_decl_index,
.namespace = .none,
.tag_ty = if (enum_field_names.len == 0)
@@ -35528,7 +35530,7 @@ fn generateUnionTagTypeSimple(
.names = enum_field_names,
.values = &.{},
.tag_mode = .auto,
- } });
+ });
const new_decl = mod.declPtr(new_decl_index);
new_decl.owns_tv = true;
@@ -35625,6 +35627,7 @@ fn getBuiltinType(sema: *Sema, name: []const u8) CompileError!Type {
/// TODO assert the return value matches `ty.onePossibleValue`
pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
const mod = sema.mod;
+ const ip = &mod.intern_pool;
return switch (ty.toIntern()) {
.u0_type,
.i0_type,
@@ -35718,7 +35721,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
.none,
=> unreachable,
- _ => switch (mod.intern_pool.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
+ _ => switch (ip.items.items(.tag)[@intFromEnum(ty.toIntern())]) {
.type_int_signed, // i0 handled above
.type_int_unsigned, // u0 handled above
.type_pointer,
@@ -35801,7 +35804,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
.type_union_tagged,
.type_union_untagged,
.type_union_safety,
- => switch (mod.intern_pool.indexToKey(ty.toIntern())) {
+ => switch (ip.indexToKey(ty.toIntern())) {
inline .array_type, .vector_type => |seq_type, seq_tag| {
const has_sentinel = seq_tag == .array_type and seq_type.sentinel != .none;
if (seq_type.len + @intFromBool(has_sentinel) == 0) return (try mod.intern(.{ .aggregate = .{
@@ -35930,7 +35933,7 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
.storage = .{ .u64 = 0 },
} })
else
- enum_type.values[0]).toValue(), ty),
+ enum_type.values.get(ip)[0]).toValue(), ty),
else => return null,
}
},