diff --git a/src/Sema.zig b/src/Sema.zig index 001d841959..4541d02f66 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -22636,6 +22636,21 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData if (dest_tag == .ErrorSet and operand_tag == .ErrorUnion) { return sema.fail(block, src, "cannot cast an error union type to error set", .{}); } + if (dest_tag == .ErrorUnion and operand_tag == .ErrorUnion and + base_dest_ty.errorUnionPayload(mod).toIntern() != base_operand_ty.errorUnionPayload(mod).toIntern()) + { + return sema.failWithOwnedErrorMsg(block, msg: { + const msg = try sema.errMsg(block, src, "payload types of error unions must match", .{}); + errdefer msg.destroy(sema.gpa); + const dest_ty = base_dest_ty.errorUnionPayload(mod); + const operand_ty = base_operand_ty.errorUnionPayload(mod); + try sema.errNote(block, src, msg, "destination payload is '{}'", .{dest_ty.fmt(mod)}); + try sema.errNote(block, src, msg, "operand payload is '{}'", .{operand_ty.fmt(mod)}); + try addDeclaredHereNote(sema, msg, dest_ty); + try addDeclaredHereNote(sema, msg, operand_ty); + break :msg msg; + }); + } const dest_ty = if (dest_tag == .ErrorUnion) base_dest_ty.errorUnionSet(mod) else base_dest_ty; const operand_ty = if (operand_tag == .ErrorUnion) base_operand_ty.errorUnionSet(mod) else base_operand_ty; diff --git a/test/cases/compile_errors/@errorCast_with_bad_type.zig b/test/cases/compile_errors/@errorCast_with_bad_type.zig index b698203737..6fc42f79f3 100644 --- a/test/cases/compile_errors/@errorCast_with_bad_type.zig +++ b/test/cases/compile_errors/@errorCast_with_bad_type.zig @@ -13,6 +13,11 @@ export fn entry3() void { const a: anyerror = @errorCast(e); _ = a; } +pub export fn entry4() void { + const a: anyerror!u32 = 123; + const b: anyerror!f32 = @errorCast(a); + _ = b; +} // error // backend=stage2 @@ -21,3 +26,6 @@ export fn entry3() void { // :4:25: error: expected error set or error union type, found 'ComptimeInt' // :8:20: error: expected error set or error union type, found 'Int' // :13:25: error: cannot cast an error union type to error set +// :18:29: error: payload types of error unions must match +// :18:29: note: destination payload is 'f32' +// :18:29: note: operand payload is 'u32'