mirror of
https://github.com/ziglang/zig.git
synced 2026-02-14 05:20:34 +00:00
stage2: @TypeInfo for error sets (#10998)
This commit is contained in:
parent
aefe4046de
commit
e999a925fa
82
src/Sema.zig
82
src/Sema.zig
@ -10146,6 +10146,87 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
}),
|
||||
);
|
||||
},
|
||||
.ErrorSet => {
|
||||
var fields_anon_decl = try block.startAnonDecl(src);
|
||||
defer fields_anon_decl.deinit();
|
||||
|
||||
// Get the Error type
|
||||
const error_field_ty = t: {
|
||||
const set_field_ty_decl = (try sema.namespaceLookup(
|
||||
block,
|
||||
src,
|
||||
type_info_ty.getNamespace().?,
|
||||
"Error",
|
||||
)).?;
|
||||
try sema.mod.declareDeclDependency(sema.owner_decl, set_field_ty_decl);
|
||||
try sema.ensureDeclAnalyzed(set_field_ty_decl);
|
||||
var buffer: Value.ToTypeBuffer = undefined;
|
||||
break :t try set_field_ty_decl.val.toType(&buffer).copy(fields_anon_decl.arena());
|
||||
};
|
||||
|
||||
// If the error set is inferred it has to be resolved at this point
|
||||
if (ty.castTag(.error_set_inferred)) |payload| {
|
||||
try sema.resolveInferredErrorSet(payload.data);
|
||||
}
|
||||
|
||||
// Build our list of Error values
|
||||
// Optional value is only null if anyerror
|
||||
// Value can be zero-length slice otherwise
|
||||
const error_field_vals: ?[]Value = if (ty.isAnyError()) null else blk: {
|
||||
const names = ty.errorSetNames();
|
||||
const vals = try fields_anon_decl.arena().alloc(Value, names.len);
|
||||
for (vals) |*field_val, i| {
|
||||
const name = names[i];
|
||||
const name_val = v: {
|
||||
var anon_decl = try block.startAnonDecl(src);
|
||||
defer anon_decl.deinit();
|
||||
const bytes = try anon_decl.arena().dupeZ(u8, name);
|
||||
const new_decl = try anon_decl.finish(
|
||||
try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len),
|
||||
try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]),
|
||||
);
|
||||
break :v try Value.Tag.decl_ref.create(fields_anon_decl.arena(), new_decl);
|
||||
};
|
||||
|
||||
const error_field_fields = try fields_anon_decl.arena().create([1]Value);
|
||||
error_field_fields.* = .{
|
||||
// name: []const u8,
|
||||
name_val,
|
||||
};
|
||||
|
||||
field_val.* = try Value.Tag.@"struct".create(
|
||||
fields_anon_decl.arena(),
|
||||
error_field_fields,
|
||||
);
|
||||
}
|
||||
|
||||
break :blk vals;
|
||||
};
|
||||
|
||||
// Build our ?[]const Error value
|
||||
const errors_val = if (error_field_vals) |vals| v: {
|
||||
const new_decl = try fields_anon_decl.finish(
|
||||
try Type.Tag.array.create(fields_anon_decl.arena(), .{
|
||||
.len = vals.len,
|
||||
.elem_type = error_field_ty,
|
||||
}),
|
||||
try Value.Tag.array.create(
|
||||
fields_anon_decl.arena(),
|
||||
vals,
|
||||
),
|
||||
);
|
||||
break :v try Value.Tag.decl_ref.create(sema.arena, new_decl);
|
||||
} else Value.@"null";
|
||||
|
||||
// Construct TypeInfo{ .ErrorSet = errors_val }
|
||||
return sema.addConstant(
|
||||
type_info_ty,
|
||||
try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = try Value.Tag.enum_field_index.create(sema.arena, @enumToInt(std.builtin.TypeId.ErrorSet)),
|
||||
.val = errors_val,
|
||||
}),
|
||||
);
|
||||
},
|
||||
.ErrorUnion => {
|
||||
const field_values = try sema.arena.alloc(Value, 2);
|
||||
// error_set: type,
|
||||
@ -10520,7 +10601,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
}),
|
||||
);
|
||||
},
|
||||
.ErrorSet => return sema.fail(block, src, "TODO: implement zirTypeInfo for ErrorSet", .{}),
|
||||
.BoundFn => @panic("TODO remove this type from the language and compiler"),
|
||||
.Frame => return sema.fail(block, src, "TODO: implement zirTypeInfo for Frame", .{}),
|
||||
.AnyFrame => return sema.fail(block, src, "TODO: implement zirTypeInfo for AnyFrame", .{}),
|
||||
|
||||
@ -176,7 +176,11 @@ fn foo2(f: fn () anyerror!void) void {
|
||||
fn bar2() (error{}!void) {}
|
||||
|
||||
test "error union type " {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testErrorUnionType();
|
||||
comptime try testErrorUnionType();
|
||||
@ -191,7 +195,11 @@ fn testErrorUnionType() !void {
|
||||
}
|
||||
|
||||
test "error set type" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testErrorSetType();
|
||||
comptime try testErrorSetType();
|
||||
@ -307,7 +315,11 @@ fn foo3(b: usize) Error!usize {
|
||||
}
|
||||
|
||||
test "error: Infer error set from literals" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
_ = nullLiteral("n") catch |err| handleErrors(err);
|
||||
_ = floatLiteral("n") catch |err| handleErrors(err);
|
||||
|
||||
@ -156,8 +156,12 @@ fn testArray() !void {
|
||||
}
|
||||
}
|
||||
|
||||
test "type info: error set, error union info" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
test "type info: error set, error union info, anyerror" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
try testErrorSet();
|
||||
comptime try testErrorSet();
|
||||
@ -185,6 +189,38 @@ fn testErrorSet() !void {
|
||||
try expect(global_info.ErrorSet == null);
|
||||
}
|
||||
|
||||
test "type info: error set single value" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const TestSet = error.One;
|
||||
|
||||
const error_set_info = @typeInfo(@TypeOf(TestSet));
|
||||
try expect(error_set_info == .ErrorSet);
|
||||
try expect(error_set_info.ErrorSet.?.len == 1);
|
||||
try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One"));
|
||||
}
|
||||
|
||||
test "type info: error set merged" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
|
||||
const TestSet = error{ One, Two } || error{Three};
|
||||
|
||||
const error_set_info = @typeInfo(TestSet);
|
||||
try expect(error_set_info == .ErrorSet);
|
||||
try expect(error_set_info.ErrorSet.?.len == 3);
|
||||
try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One"));
|
||||
try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two"));
|
||||
try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three"));
|
||||
}
|
||||
|
||||
test "type info: enum info" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user