mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
stage2: reify error sets
This commit is contained in:
parent
65943010c7
commit
7deadf4301
34
src/Sema.zig
34
src/Sema.zig
@ -10397,7 +10397,13 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
vals,
|
||||
),
|
||||
);
|
||||
break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
|
||||
|
||||
const new_decl_val = try Value.Tag.decl_ref.create(sema.arena, new_decl);
|
||||
const slice_val = try Value.Tag.slice.create(sema.arena, .{
|
||||
.ptr = new_decl_val,
|
||||
.len = try Value.Tag.int_u64.create(sema.arena, vals.len),
|
||||
});
|
||||
break :v try Value.Tag.opt_payload.create(sema.arena, slice_val);
|
||||
} else Value.@"null";
|
||||
|
||||
// Construct TypeInfo{ .ErrorSet = errors_val }
|
||||
@ -12317,7 +12323,31 @@ fn zirReify(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I
|
||||
});
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.ErrorSet => return sema.fail(block, src, "TODO: Sema.zirReify for ErrorSet", .{}),
|
||||
.ErrorSet => {
|
||||
const payload_val = union_val.val.optionalValue() orelse
|
||||
return sema.addType(Type.initTag(.anyerror));
|
||||
const slice_val = payload_val.castTag(.slice).?.data;
|
||||
const decl = slice_val.ptr.castTag(.decl_ref).?.data;
|
||||
try sema.ensureDeclAnalyzed(decl);
|
||||
const array_val = decl.val.castTag(.array).?.data;
|
||||
|
||||
var names: Module.ErrorSet.NameMap = .{};
|
||||
try names.ensureUnusedCapacity(sema.arena, array_val.len);
|
||||
for (array_val) |elem_val| {
|
||||
const struct_val = elem_val.castTag(.@"struct").?.data;
|
||||
// TODO use reflection instead of magic numbers here
|
||||
// error_set: type,
|
||||
const name_val = struct_val[0];
|
||||
|
||||
names.putAssumeCapacityNoClobber(
|
||||
try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena),
|
||||
{},
|
||||
);
|
||||
}
|
||||
|
||||
const ty = try Type.Tag.error_set_merged.create(sema.arena, names);
|
||||
return sema.addType(ty);
|
||||
},
|
||||
.Enum => return sema.fail(block, src, "TODO: Sema.zirReify for Enum", .{}),
|
||||
.Union => return sema.fail(block, src, "TODO: Sema.zirReify for Union", .{}),
|
||||
.Fn => return sema.fail(block, src, "TODO: Sema.zirReify for Fn", .{}),
|
||||
|
||||
@ -2506,6 +2506,15 @@ pub const Value = extern union {
|
||||
};
|
||||
}
|
||||
|
||||
/// Value of the optional, null if optional has no payload.
|
||||
pub fn optionalValue(val: Value) ?Value {
|
||||
if (val.isNull()) return null;
|
||||
|
||||
// Valid for optional representation to be the direct value
|
||||
// and not use opt_payload.
|
||||
return if (val.castTag(.opt_payload)) |p| p.data else val;
|
||||
}
|
||||
|
||||
/// Valid for all types. Asserts the value is not undefined.
|
||||
pub fn isFloat(self: Value) bool {
|
||||
return switch (self.tag()) {
|
||||
|
||||
@ -240,12 +240,19 @@ fn add(a: i32, b: i32) i32 {
|
||||
}
|
||||
|
||||
test "Type.ErrorSet" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
try testing.expect(@Type(TypeInfo{ .ErrorSet = null }) == anyerror);
|
||||
|
||||
// error sets don't compare equal so just check if they compile
|
||||
_ = @Type(@typeInfo(error{}));
|
||||
_ = @Type(@typeInfo(error{A}));
|
||||
_ = @Type(@typeInfo(error{ A, B, C }));
|
||||
_ = @Type(TypeInfo{
|
||||
.ErrorSet = &[_]TypeInfo.Error{
|
||||
.{ .name = "A" },
|
||||
.{ .name = "B" },
|
||||
.{ .name = "C" },
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
test "Type.Struct" {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user