Commit edfbf85ecd

Andrew Kelley <andrew@ziglang.org>
2021-05-04 22:58:08
Sema: implement error sets
1 parent 230ce72
Changed files (3)
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 {
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];
+
+    var new_decl_arena = std.heap.ArenaAllocator.init(gpa);
 
-    return sema.mod.fail(&block.base, sema.src, "TODO implement zirErrorSetDecl", .{});
+    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(
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,