diff --git a/BRANCH_TODO b/BRANCH_TODO index e64354dcbc..c6e2db4745 100644 --- a/BRANCH_TODO +++ b/BRANCH_TODO @@ -118,31 +118,9 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool { return mod.failWithOwnedErrorMsg(scope, msg); } - - 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); - - - // when implementing this be sure to add test coverage for the asm return type // not resolving into a type (the node_offset_asm_ret_ty field of LazySrcLoc) - - pub fn analyzeNamespace( mod: *Module, namespace: *Scope.Namespace, diff --git a/src/Module.zig b/src/Module.zig index 4b421241cd..3f88efd717 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -478,6 +478,7 @@ pub const ErrorSet = struct { names_len: u32, /// The string bytes are stored in the owner Decl arena. /// They are in the same order they appear in the AST. + /// The length is given by `names_len`. names_ptr: [*]const []const u8, pub fn srcLoc(self: ErrorSet) SrcLoc { diff --git a/src/Sema.zig b/src/Sema.zig index 34713234c8..46b230f174 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -908,11 +908,33 @@ fn zirErrorSetDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Inner const tracy = trace(@src()); defer tracy.end(); + const gpa = sema.gpa; 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); + const fields = sema.code.extra[extra.end..][0..extra.data.fields_len]; - return sema.mod.fail(&block.base, sema.src, "TODO implement zirErrorSetDecl", .{}); + var new_decl_arena = std.heap.ArenaAllocator.init(gpa); + + const error_set = try new_decl_arena.allocator.create(Module.ErrorSet); + const error_set_ty = try Type.Tag.error_set.create(&new_decl_arena.allocator, error_set); + const error_set_val = try Value.Tag.ty.create(&new_decl_arena.allocator, error_set_ty); + const new_decl = try sema.mod.createAnonymousDecl(&block.base, .{ + .ty = Type.initTag(.type), + .val = error_set_val, + }); + const names = try new_decl_arena.allocator.alloc([]const u8, fields.len); + for (fields) |str_index, i| { + names[i] = try new_decl_arena.allocator.dupe(u8, sema.code.nullTerminatedString(str_index)); + } + error_set.* = .{ + .owner_decl = new_decl, + .node_offset = inst_data.src_node, + .names_ptr = names.ptr, + .names_len = @intCast(u32, names.len), + }; + try new_decl.finalizeNewArena(&new_decl_arena); + return sema.analyzeDeclVal(block, src, new_decl); } fn zirRetPtr(