authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-02 19:01:55-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-02 22:01:55-05:00
logac7028f559d888f61f19589c1ead1f6cdeace736
treebf88fc6513bbc2943c2c36abd25fd3ea36424951
parentf5e2e301e98fe93f63b5b997e03fa73ed1798a26
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

stage2: implement @errSetCast (#11039)


3 files changed, 64 insertions(+), 4 deletions(-)

src/Sema.zig+40-1
......@@ -12465,7 +12465,39 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1246512465fn zirErrSetCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
1246612466 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
1246712467 const src = inst_data.src();
12468 return sema.fail(block, src, "TODO: Sema.zirErrSetCast", .{});
12468 const dest_ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
12469 const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
12470 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
12471 const dest_ty = try sema.resolveType(block, dest_ty_src, extra.lhs);
12472 const operand = sema.resolveInst(extra.rhs);
12473 const operand_ty = sema.typeOf(operand);
12474 try sema.checkErrorSetType(block, dest_ty_src, dest_ty);
12475 try sema.checkErrorSetType(block, operand_src, operand_ty);
12476
12477 if (try sema.resolveDefinedValue(block, operand_src, operand)) |val| {
12478 try sema.resolveInferredErrorSetTy(dest_ty);
12479
12480 if (!dest_ty.isAnyError()) {
12481 const error_name = val.castTag(.@"error").?.data.name;
12482 if (!dest_ty.errorSetHasField(error_name)) {
12483 return sema.fail(
12484 block,
12485 src,
12486 "error.{s} not a member of error set '{}'",
12487 .{ error_name, dest_ty },
12488 );
12489 }
12490 }
12491
12492 return sema.addConstant(dest_ty, val);
12493 }
12494
12495 try sema.requireRuntimeBlock(block, src);
12496 if (block.wantSafety()) {
12497 // TODO
12498 }
12499
12500 return block.addBitCast(dest_ty, operand);
1246912501}
1247012502
1247112503fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
......@@ -12983,6 +13015,13 @@ fn checkIntOrVector(
1298313015 }
1298413016}
1298513017
13018fn checkErrorSetType(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) CompileError!void {
13019 switch (ty.zigTypeTag()) {
13020 .ErrorSet => return,
13021 else => return sema.fail(block, src, "expected error set type, found '{}'", .{ty}),
13022 }
13023}
13024
1298613025const SimdBinOp = struct {
1298713026 len: ?usize,
1298813027 /// Coerced to `result_ty`.
src/value.zig+17-2
......@@ -2067,10 +2067,25 @@ pub const Value = extern union {
20672067 }
20682068 },
20692069 .ErrorUnion => {
2070 @panic("TODO implement hashing error union values");
2070 if (val.tag() == .@"error") {
2071 std.hash.autoHash(hasher, false); // error
2072 const sub_ty = ty.errorUnionSet();
2073 val.hash(sub_ty, hasher);
2074 return;
2075 }
2076
2077 if (val.castTag(.eu_payload)) |payload| {
2078 std.hash.autoHash(hasher, true); // payload
2079 const sub_ty = ty.errorUnionPayload();
2080 payload.data.hash(sub_ty, hasher);
2081 return;
2082 } else unreachable;
20712083 },
20722084 .ErrorSet => {
2073 @panic("TODO implement hashing error set values");
2085 // just hash the literal error value. this is the most stable
2086 // thing between compiler invocations. we can't use the error
2087 // int cause (1) its not stable and (2) we don't have access to mod.
2088 hasher.update(val.getError().?);
20742089 },
20752090 .Enum => {
20762091 var enum_space: Payload.U64 = undefined;
test/behavior/error.zig+7-1
......@@ -209,7 +209,11 @@ fn testErrorSetType() !void {
209209}
210210
211211test "explicit error set cast" {
212 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
212 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
213 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
214 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
215 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
216 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
213217
214218 try testExplicitErrorSetCast(Set1.A);
215219 comptime try testExplicitErrorSetCast(Set1.A);
......@@ -220,7 +224,9 @@ const Set2 = error{ A, C };
220224
221225fn testExplicitErrorSetCast(set1: Set1) !void {
222226 var x = @errSetCast(Set2, set1);
227 try expect(@TypeOf(x) == Set2);
223228 var y = @errSetCast(Set1, x);
229 try expect(@TypeOf(y) == Set1);
224230 try expect(y == error.A);
225231}
226232