mirror of
https://github.com/ziglang/zig.git
synced 2026-02-20 08:14:48 +00:00
stage2: implement @errSetCast (#11039)
This commit is contained in:
parent
f5e2e301e9
commit
ac7028f559
41
src/Sema.zig
41
src/Sema.zig
@ -12465,7 +12465,39 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
|
||||
fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
|
||||
const src = inst_data.src();
|
||||
return sema.fail(block, src, "TODO: Sema.zirErrSetCast", .{});
|
||||
const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
|
||||
const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
|
||||
const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
|
||||
const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
|
||||
const operand = sema.resolveInst(extra.rhs);
|
||||
const operand_ty = sema.typeOf(operand);
|
||||
try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
|
||||
try sema.checkErrorSetType(block, operand_src, operand_ty);
|
||||
|
||||
if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
|
||||
try sema.resolveInferredErrorSetTy(dest_ty);
|
||||
|
||||
if (!dest_ty.isAnyError()) {
|
||||
const error_name = val.castTag(.@"error").?.data.name;
|
||||
if (!dest_ty.errorSetHasField(error_name)) {
|
||||
return sema.fail(
|
||||
block,
|
||||
src,
|
||||
"error.{s} not a member of error set '{}'",
|
||||
.{ error_name, dest_ty },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return sema.addConstant(dest_ty, val);
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
if (block.wantSafety()) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
return block.addBitCast(dest_ty, operand);
|
||||
}
|
||||
|
||||
fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
|
||||
@ -12983,6 +13015,13 @@ fn checkIntOrVector(
|
||||
}
|
||||
}
|
||||
|
||||
fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
|
||||
switch (ty.zigTypeTag()) {
|
||||
.ErrorSet => return,
|
||||
else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty}),
|
||||
}
|
||||
}
|
||||
|
||||
const SimdBinOp = struct {
|
||||
len: ?usize,
|
||||
/// Coerced to `result_ty`.
|
||||
|
||||
@ -2067,10 +2067,25 @@ pub const Value = extern union {
|
||||
}
|
||||
},
|
||||
.ErrorUnion => {
|
||||
@panic("TODO implement hashing error union values");
|
||||
if (val.tag() == .@"error") {
|
||||
std.hash.autoHash(hasher, false); // error
|
||||
const sub_ty = ty.errorUnionSet();
|
||||
val.hash(sub_ty, hasher);
|
||||
return;
|
||||
}
|
||||
|
||||
if (val.castTag(.eu_payload)) |payload| {
|
||||
std.hash.autoHash(hasher, true); // payload
|
||||
const sub_ty = ty.errorUnionPayload();
|
||||
payload.data.hash(sub_ty, hasher);
|
||||
return;
|
||||
} else unreachable;
|
||||
},
|
||||
.ErrorSet => {
|
||||
@panic("TODO implement hashing error set values");
|
||||
// just hash the literal error value. this is the most stable
|
||||
// thing between compiler invocations. we can't use the error
|
||||
// int cause (1) its not stable and (2) we don't have access to mod.
|
||||
hasher.update(val.getError().?);
|
||||
},
|
||||
.Enum => {
|
||||
var enum_space: Payload.U64 = undefined;
|
||||
|
||||
@ -209,7 +209,11 @@ fn testErrorSetType() !void {
|
||||
}
|
||||
|
||||
test "explicit error set cast" {
|
||||
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 testExplicitErrorSetCast(Set1.A);
|
||||
comptime try testExplicitErrorSetCast(Set1.A);
|
||||
@ -220,7 +224,9 @@ const Set2 = error{ A, C };
|
||||
|
||||
fn testExplicitErrorSetCast(set1: Set1) !void {
|
||||
var x = @errSetCast(Set2, set1);
|
||||
try expect(@TypeOf(x) == Set2);
|
||||
var y = @errSetCast(Set1, x);
|
||||
try expect(@TypeOf(y) == Set1);
|
||||
try expect(y == error.A);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user