authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-11 11:38:04+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-11 11:59:26+03:00
log0370006c1f5a23e5e2d0993fb71f825791d64957
tree9be5ac0a09bd6c2a7efa711b652d6a1c2e57b152
parente644a2ab6a99951ac8d367f7a6bac985cf16f9cc

Sema: only add note about int mismatch if not coercible

`unsigned 64-bit int cannot represent all possible unsigned 63-bit values` is nonsensical.

2 files changed, 25 insertions(+), 7 deletions(-)

src/Sema.zig+14-6
......@@ -20411,7 +20411,7 @@ fn coerceExtra(
2041120411const InMemoryCoercionResult = union(enum) {
2041220412 ok,
2041320413 no_match: Pair,
20414 int_mismatch: Int,
20414 int_not_coercible: Int,
2041520415 error_union_payload: PairAndChild,
2041620416 array_len: IntPair,
2041720417 array_sentinel: Sentinel,
......@@ -20527,7 +20527,7 @@ const InMemoryCoercionResult = union(enum) {
2052720527 try sema.addDeclaredHereNote(msg, types.actual);
2052820528 break;
2052920529 },
20530 .int_mismatch => |int| {
20530 .int_not_coercible => |int| {
2053120531 try sema.errNote(block, src, msg, "{s} {d}-bit int cannot represent all possible {s} {d}-bit values", .{
2053220532 @tagName(int.wanted_signedness), int.wanted_bits, @tagName(int.actual_signedness), int.actual_bits,
2053320533 });
......@@ -20768,17 +20768,25 @@ fn coerceInMemoryAllowed(
2076820768 if (dest_ty.zigTypeTag() == .Int and src_ty.zigTypeTag() == .Int) {
2076920769 const dest_info = dest_ty.intInfo(target);
2077020770 const src_info = src_ty.intInfo(target);
20771 if (dest_info.signedness != src_info.signedness or
20772 dest_info.bits != src_info.bits)
20771
20772 if (dest_info.signedness == src_info.signedness and
20773 dest_info.bits == src_info.bits)
20774 {
20775 return .ok;
20776 }
20777
20778 if ((src_info.signedness == dest_info.signedness and dest_info.bits < src_info.bits) or
20779 // small enough unsigned ints can get casted to large enough signed ints
20780 (dest_info.signedness == .signed and (src_info.signedness == .unsigned or dest_info.bits <= src_info.bits)) or
20781 (dest_info.signedness == .unsigned and src_info.signedness == .signed))
2077320782 {
20774 return InMemoryCoercionResult{ .int_mismatch = .{
20783 return InMemoryCoercionResult{ .int_not_coercible = .{
2077520784 .actual_signedness = src_info.signedness,
2077620785 .wanted_signedness = dest_info.signedness,
2077720786 .actual_bits = src_info.bits,
2077820787 .wanted_bits = dest_info.bits,
2077920788 } };
2078020789 }
20781 return .ok;
2078220790 }
2078320791
2078420792 // Differently-named floats with the same number of bits.
test/cases/compile_errors/cast_between_optional_T_where_T_is_not_a_pointer.zig+11-1
......@@ -1,11 +1,18 @@
11pub const fnty1 = ?*const fn (i8) void;
22pub const fnty2 = ?*const fn (u64) void;
3export fn entry() void {
3export fn entry1() void {
44 var a: fnty1 = undefined;
55 var b: fnty2 = undefined;
66 a = b;
77}
88
9pub const fnty3 = ?*const fn (u63) void;
10export fn entry2() void {
11 var a: fnty3 = undefined;
12 var b: fnty2 = undefined;
13 a = b;
14}
15
916// error
1017// backend=stage2
1118// target=native
......@@ -14,3 +21,6 @@ export fn entry() void {
1421// :6:9: note: pointer type child 'fn(u64) void' cannot cast into pointer type child 'fn(i8) void'
1522// :6:9: note: parameter 0 'u64' cannot cast into 'i8'
1623// :6:9: note: unsigned 64-bit int cannot represent all possible signed 8-bit values
24// :13:9: error: expected type '?*const fn(u63) void', found '?*const fn(u64) void'
25// :13:9: note: pointer type child 'fn(u64) void' cannot cast into pointer type child 'fn(u63) void'
26// :13:9: note: parameter 0 'u64' cannot cast into 'u63'