authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-02-05 20:13:56+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-02-05 20:13:56+00:00
logcac814cf58ca65ffd8081dca6f2f5b26d822ef5d
treea47d2a1e449630d66526acbb73e4714cffee52fc
parent9ba9f457be13c0c32981e94cf75ba7ea6619d92f
signaturelock-open Commit is signed but in an unrecognized format.

Sema: fix comparison between error set and comptime-known error union

Resolves: #20613

2 files changed, 19 insertions(+), 1 deletions(-)

src/Sema.zig+8-1
......@@ -9145,6 +9145,7 @@ fn zirErrUnionCode(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro
91459145 return sema.analyzeErrUnionCode(block, src, operand);
91469146}
91479147
9148/// If `operand` is comptime-known, asserts that it is an error value rather than a payload value.
91489149fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Inst.Ref) CompileError!Air.Inst.Ref {
91499150 const pt = sema.pt;
91509151 const zcu = pt.zcu;
......@@ -17599,10 +17600,16 @@ fn analyzeCmp(
1759917600 return sema.cmpNumeric(block, src, lhs, rhs, op, lhs_src, rhs_src);
1760017601 }
1760117602 if (is_equality_cmp and lhs_ty.zigTypeTag(zcu) == .error_union and rhs_ty.zigTypeTag(zcu) == .error_set) {
17603 if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| {
17604 if (lhs_val.errorUnionIsPayload(zcu)) return .bool_false;
17605 }
1760217606 const casted_lhs = try sema.analyzeErrUnionCode(block, lhs_src, lhs);
1760317607 return sema.cmpSelf(block, src, casted_lhs, rhs, op, lhs_src, rhs_src);
1760417608 }
1760517609 if (is_equality_cmp and lhs_ty.zigTypeTag(zcu) == .error_set and rhs_ty.zigTypeTag(zcu) == .error_union) {
17610 if (try sema.resolveDefinedValue(block, rhs_src, rhs)) |rhs_val| {
17611 if (rhs_val.errorUnionIsPayload(zcu)) return .bool_false;
17612 }
1760617613 const casted_rhs = try sema.analyzeErrUnionCode(block, rhs_src, rhs);
1760717614 return sema.cmpSelf(block, src, lhs, casted_rhs, op, lhs_src, rhs_src);
1760817615 }
......@@ -23254,7 +23261,7 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2325423261 zcu.backendSupportsFeature(.error_set_has_value))
2325523262 {
2325623263 if (dest_tag == .error_union) {
23257 const err_code = try sema.analyzeErrUnionCode(block, operand_src, operand);
23264 const err_code = try block.addTyOp(.unwrap_errunion_err, operand_ty, operand);
2325823265 const err_int = try block.addBitCast(err_int_ty, err_code);
2325923266 const zero_err = try pt.intRef(try pt.errorIntType(), 0);
2326023267
test/behavior/error.zig+11
......@@ -1100,3 +1100,14 @@ test "return error union with i65" {
11001100fn add(x: i65, y: i65) anyerror!i65 {
11011101 return x + y;
11021102}
1103
1104test "compare error union to error set" {
1105 const S = struct {
1106 fn doTheTest(val: error{Foo}!i32) !void {
1107 if (error.Foo == val) return error.Unexpected;
1108 if (val == error.Foo) return error.Unexpected;
1109 }
1110 };
1111 try S.doTheTest(0);
1112 try comptime S.doTheTest(0);
1113}