authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-03-28 15:37:48+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-03-28 15:39:47+02:00
log9106fdffaf772283acaa2fd24f9789d431a25586
tree2be2310f30c3f7cbd69456ad0d1944e9c55885b8
parent60614b2a854df0732d0d215a236cf051afd4f832

Sema: check error union payload types in `@errorCast`


2 files changed, 23 insertions(+), 0 deletions(-)

src/Sema.zig+15
......@@ -22636,6 +22636,21 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2263622636 if (dest_tag == .ErrorSet and operand_tag == .ErrorUnion) {
2263722637 return sema.fail(block, src, "cannot cast an error union type to error set", .{});
2263822638 }
22639 if (dest_tag == .ErrorUnion and operand_tag == .ErrorUnion and
22640 base_dest_ty.errorUnionPayload(mod).toIntern() != base_operand_ty.errorUnionPayload(mod).toIntern())
22641 {
22642 return sema.failWithOwnedErrorMsg(block, msg: {
22643 const msg = try sema.errMsg(block, src, "payload types of error unions must match", .{});
22644 errdefer msg.destroy(sema.gpa);
22645 const dest_ty = base_dest_ty.errorUnionPayload(mod);
22646 const operand_ty = base_operand_ty.errorUnionPayload(mod);
22647 try sema.errNote(block, src, msg, "destination payload is '{}'", .{dest_ty.fmt(mod)});
22648 try sema.errNote(block, src, msg, "operand payload is '{}'", .{operand_ty.fmt(mod)});
22649 try addDeclaredHereNote(sema, msg, dest_ty);
22650 try addDeclaredHereNote(sema, msg, operand_ty);
22651 break :msg msg;
22652 });
22653 }
2263922654 const dest_ty = if (dest_tag == .ErrorUnion) base_dest_ty.errorUnionSet(mod) else base_dest_ty;
2264022655 const operand_ty = if (operand_tag == .ErrorUnion) base_operand_ty.errorUnionSet(mod) else base_operand_ty;
2264122656
test/cases/compile_errors/@errorCast_with_bad_type.zig+8
......@@ -13,6 +13,11 @@ export fn entry3() void {
1313 const a: anyerror = @errorCast(e);
1414 _ = a;
1515}
16pub export fn entry4() void {
17 const a: anyerror!u32 = 123;
18 const b: anyerror!f32 = @errorCast(a);
19 _ = b;
20}
1621
1722// error
1823// backend=stage2
......@@ -21,3 +26,6 @@ export fn entry3() void {
2126// :4:25: error: expected error set or error union type, found 'ComptimeInt'
2227// :8:20: error: expected error set or error union type, found 'Int'
2328// :13:25: error: cannot cast an error union type to error set
29// :18:29: error: payload types of error unions must match
30// :18:29: note: destination payload is 'f32'
31// :18:29: note: operand payload is 'u32'