Sema: implement error sets

This commit is contained in:
Andrew Kelley 2021-05-04 13:58:08 -07:00
parent 230ce72f16
commit edfbf85ecd
3 changed files with 24 additions and 23 deletions

View File

@ -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,

View File

@ -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 {

View File

@ -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(