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...@@ -22636,6 +22636,21 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
22636 if (dest_tag == .ErrorSet and operand_tag == .ErrorUnion) {22636 if (dest_tag == .ErrorSet and operand_tag == .ErrorUnion) {
22637 return sema.fail(block, src, "cannot cast an error union type to error set", .{});22637 return sema.fail(block, src, "cannot cast an error union type to error set", .{});
22638 }22638 }
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 }
22639 const dest_ty = if (dest_tag == .ErrorUnion) base_dest_ty.errorUnionSet(mod) else base_dest_ty;22654 const dest_ty = if (dest_tag == .ErrorUnion) base_dest_ty.errorUnionSet(mod) else base_dest_ty;
22640 const operand_ty = if (operand_tag == .ErrorUnion) base_operand_ty.errorUnionSet(mod) else base_operand_ty;22655 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 {...@@ -13,6 +13,11 @@ export fn entry3() void {
13 const a: anyerror = @errorCast(e);13 const a: anyerror = @errorCast(e);
14 _ = a;14 _ = a;
15}15}
16pub export fn entry4() void {
17 const a: anyerror!u32 = 123;
18 const b: anyerror!f32 = @errorCast(a);
19 _ = b;
20}
1621
17// error22// error
18// backend=stage223// backend=stage2
...@@ -21,3 +26,6 @@ export fn entry3() void {...@@ -21,3 +26,6 @@ export fn entry3() void {
21// :4:25: error: expected error set or error union type, found 'ComptimeInt'26// :4:25: error: expected error set or error union type, found 'ComptimeInt'
22// :8:20: error: expected error set or error union type, found 'Int'27// :8:20: error: expected error set or error union type, found 'Int'
23// :13:25: error: cannot cast an error union type to error set28// :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'