diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2023-08-17 14:25:18 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2023-08-17 18:16:03 -0700 |
| commit | 7ef1eb1c27754cb0349fdc10db1f02ff2dddd99b (patch) | |
| tree | 6a76839d8be347648741e17f50d6c70d8313adc3 /src/Sema.zig | |
| parent | 8c1329b222ab620d7388d766e9e558baa502ce93 (diff) | |
| download | zig-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.zig | 31 |
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, } }, |
