Commit 7f931a7522
Changed files (4)
src/AstGen.zig
@@ -1463,6 +1463,7 @@ fn blockExprStmts(
.enum_decl,
.enum_decl_nonexhaustive,
.opaque_decl,
+ .error_set_decl,
.int_to_enum,
.enum_to_int,
.type_info,
@@ -2930,11 +2931,37 @@ fn errorSetDecl(
node: ast.Node.Index,
) InnerError!Zir.Inst.Ref {
const astgen = gz.astgen;
+ const gpa = astgen.gpa;
const tree = &astgen.file.tree;
const main_tokens = tree.nodes.items(.main_token);
const token_tags = tree.tokens.items(.tag);
- return astgen.failNode(node, "TODO AstGen errorSetDecl", .{});
+ var field_names: std.ArrayListUnmanaged(u32) = .{};
+ defer field_names.deinit(gpa);
+
+ {
+ const error_token = main_tokens[node];
+ var tok_i = error_token + 2;
+ var field_i: usize = 0;
+ while (true) : (tok_i += 1) {
+ switch (token_tags[tok_i]) {
+ .doc_comment, .comma => {},
+ .identifier => {
+ const str_index = try gz.identAsString(tok_i);
+ try field_names.append(gpa, str_index);
+ field_i += 1;
+ },
+ .r_brace => break,
+ else => unreachable,
+ }
+ }
+ }
+
+ const result = try gz.addPlNode(.error_set_decl, node, Zir.Inst.ErrorSetDecl{
+ .fields_len = @intCast(u32, field_names.items.len),
+ });
+ try astgen.extra.appendSlice(gpa, field_names.items);
+ return rvalue(gz, scope, rl, result, node);
}
fn orelseCatchExpr(
src/Sema.zig
@@ -343,6 +343,7 @@ pub fn analyzeBody(
.enum_decl_nonexhaustive => try sema.zirEnumDecl(block, inst, true),
.union_decl => try sema.zirUnionDecl(block, inst),
.opaque_decl => try sema.zirOpaqueDecl(block, inst),
+ .error_set_decl => try sema.zirErrorSetDecl(block, inst),
.add => try sema.zirArithmetic(block, inst),
.addwrap => try sema.zirArithmetic(block, inst),
@@ -978,6 +979,17 @@ fn zirOpaqueDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerEr
return sema.mod.fail(&block.base, sema.src, "TODO implement zirOpaqueDecl", .{});
}
+fn zirErrorSetDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
+ const tracy = trace(@src());
+ defer tracy.end();
+
+ const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
+ const src = inst_data.src();
+ const extra = sema.code.extraData(Zir.Inst.ErrorSetDecl, inst_data.payload_index);
+
+ return sema.mod.fail(&block.base, sema.src, "TODO implement zirErrorSetDecl", .{});
+}
+
fn zirRetPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
src/Zir.zig
@@ -307,6 +307,9 @@ pub const Inst = struct {
/// An opaque type definition. Provides an AST node only.
/// Uses the `node` union field.
opaque_decl,
+ /// An error set type definition. Contains a list of field names.
+ /// Uses the `pl_node` union field. Payload is `ErrorSetDecl`.
+ error_set_decl,
/// Declares the beginning of a statement. Used for debug info.
/// Uses the `node` union field.
dbg_stmt_node,
@@ -986,6 +989,7 @@ pub const Inst = struct {
.enum_decl,
.enum_decl_nonexhaustive,
.opaque_decl,
+ .error_set_decl,
.dbg_stmt_node,
.decl_ref,
.decl_val,
@@ -2011,6 +2015,11 @@ pub const Inst = struct {
fields_len: u32,
};
+ /// Trailing: field_name: u32 // for every field: null terminated string index
+ pub const ErrorSetDecl = struct {
+ fields_len: u32,
+ };
+
/// A f128 value, broken up into 4 u32 parts.
pub const Float128 = struct {
piece0: u32,
@@ -2328,6 +2337,8 @@ const Writer = struct {
.builtin_async_call,
=> try self.writePlNode(stream, inst),
+ .error_set_decl => try self.writePlNodeErrorSetDecl(stream, inst),
+
.add_with_overflow,
.sub_with_overflow,
.mul_with_overflow,
@@ -2596,11 +2607,7 @@ const Writer = struct {
try stream.print("\"{}\")", .{std.zig.fmtEscapes(str)});
}
- fn writePlNode(
- self: *Writer,
- stream: anytype,
- inst: Inst.Index,
- ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
+ fn writePlNode(self: *Writer, stream: anytype, inst: Inst.Index) !void {
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
try stream.writeAll("TODO) ");
try self.writeSrc(stream, inst_data.src());
@@ -2616,6 +2623,25 @@ const Writer = struct {
try self.writeSrc(stream, inst_data.src());
}
+ fn writePlNodeErrorSetDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
+ const inst_data = self.code.instructions.items(.data)[inst].pl_node;
+ const extra = self.code.extraData(Inst.ErrorSetDecl, inst_data.payload_index);
+ const fields = self.code.extra[extra.end..][0..extra.data.fields_len];
+
+ try stream.writeAll("{\n");
+ self.indent += 2;
+ for (fields) |str_index| {
+ const name = self.code.nullTerminatedString(str_index);
+ try stream.writeByteNTimes(' ', self.indent);
+ try stream.print("{},\n", .{std.zig.fmtId(name)});
+ }
+ self.indent -= 2;
+ try stream.writeByteNTimes(' ', self.indent);
+ try stream.writeAll("}) ");
+
+ try self.writeSrc(stream, inst_data.src());
+ }
+
fn writePlNodeOverflowArithmetic(self: *Writer, stream: anytype, inst: Inst.Index) !void {
const inst_data = self.code.instructions.items(.data)[inst].pl_node;
const extra = self.code.extraData(Inst.OverflowArithmetic, inst_data.payload_index).data;
BRANCH_TODO
@@ -604,73 +604,6 @@ fn astgenAndSemaVarDecl(
}
-fn errorSetDecl(
- gz: *GenZir,
- scope: *Scope,
- rl: ResultLoc,
- node: ast.Node.Index,
-) InnerError!Zir.Inst.Ref {
- const astgen = gz.astgen;
- const tree = &astgen.file.tree;
- const main_tokens = tree.nodes.items(.main_token);
- const token_tags = tree.tokens.items(.tag);
-
- // Count how many fields there are.
- const error_token = main_tokens[node];
- const count: usize = count: {
- var tok_i = error_token + 2;
- var count: usize = 0;
- while (true) : (tok_i += 1) {
- switch (token_tags[tok_i]) {
- .doc_comment, .comma => {},
- .identifier => count += 1,
- .r_brace => break :count count,
- else => unreachable,
- }
- } else unreachable; // TODO should not need else unreachable here
- };
-
- const gpa = astgen.gpa;
- var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
- errdefer new_decl_arena.deinit();
- const arena = &new_decl_arena.allocator;
-
- const fields = try arena.alloc([]const u8, count);
- {
- var tok_i = error_token + 2;
- var field_i: usize = 0;
- while (true) : (tok_i += 1) {
- switch (token_tags[tok_i]) {
- .doc_comment, .comma => {},
- .identifier => {
- fields[field_i] = try astgen.identifierTokenStringTreeArena(tok_i, tree, arena);
- field_i += 1;
- },
- .r_brace => break,
- else => unreachable,
- }
- }
- }
- const error_set = try arena.create(Module.ErrorSet);
- error_set.* = .{
- .owner_decl = astgen.decl,
- .node_offset = astgen.decl.nodeIndexToRelative(node),
- .names_ptr = fields.ptr,
- .names_len = @intCast(u32, fields.len),
- };
- const error_set_ty = try Type.Tag.error_set.create(arena, error_set);
- const error_set_val = try Value.Tag.ty.create(arena, error_set_ty);
- const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{
- .ty = Type.initTag(.type),
- .val = error_set_val,
- });
- const decl_index = try mod.declareDeclDependency(astgen.decl, new_decl);
- const result = try gz.addDecl(.decl_val, decl_index, node);
- return rvalue(gz, scope, rl, result, node);
-}
-
-
-
if (mod.lookupIdentifier(scope, ident_name)) |decl| {
const msg = msg: {
const msg = try mod.errMsg(
@@ -761,3 +694,20 @@ fn errorSetDecl(
);
}
+
+ const error_set = try arena.create(Module.ErrorSet);
+ error_set.* = .{
+ .owner_decl = astgen.decl,
+ .node_offset = astgen.decl.nodeIndexToRelative(node),
+ .names_ptr = fields.ptr,
+ .names_len = @intCast(u32, fields.len),
+ };
+ const error_set_ty = try Type.Tag.error_set.create(arena, error_set);
+ const error_set_val = try Value.Tag.ty.create(arena, error_set_ty);
+ const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{
+ .ty = Type.initTag(.type),
+ .val = error_set_val,
+ });
+ const decl_index = try mod.declareDeclDependency(astgen.decl, new_decl);
+ const result = try gz.addDecl(.decl_val, decl_index, node);
+ return rvalue(gz, scope, rl, result, node);