authorgravatar for iokg04@gmail.comRue04 <iokg04@gmail.com> 2026-07-15 23:04:54+02:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-07-15 23:04:54+02:00
log20befa4e64f1654fa3c69a0e7b0b194193c2ab27
treee84c24f4d6a99cd6ff756f6bc80ed8c86f6be1b6
parent9908b10d928a12731a288bd59068151d386efdac

Sema: fix crash on invalid coercion from error union or optional

It seems the destination and source types were switched by accident, leading to an `unreachable` being reached in the following cases: ```zig test { const eu: anyerror!u8 = 10; const i: comptime_int = eu; _ = i; } test { const op: ?u8 = 10; const i: comptime_int = op; _ = i; } ``` Resolves: https://codeberg.org/ziglang/zig/issues/30597 Resolves: https://github.com/ziglang/zig/issues/25645 Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35662 Reviewed-by: mlugg <mlugg@noreply.codeberg.org>

2 files changed, 32 insertions(+), 2 deletions(-)

src/Sema.zig+2-2
......@@ -28356,7 +28356,7 @@ fn coerceExtra(
2835628356
2835728357 // E!T to T
2835828358 if (inst_ty.zigTypeTag(zcu) == .error_union and
28359 (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, null)) == .ok)
28359 (try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty.errorUnionPayload(zcu), false, target, dest_ty_src, inst_src, null)) == .ok)
2836028360 {
2836128361 try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{});
2836228362 try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{});
......@@ -28364,7 +28364,7 @@ fn coerceExtra(
2836428364
2836528365 // ?T to T
2836628366 if (inst_ty.zigTypeTag(zcu) == .optional and
28367 (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src, null)) == .ok)
28367 (try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty.optionalChild(zcu), false, target, dest_ty_src, inst_src, null)) == .ok)
2836828368 {
2836928369 try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{});
2837028370 try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{});
test/cases/compile_errors/coercion_from_eu_or_optional_containing_or_to_comptime_int.zig created+30
......@@ -0,0 +1,30 @@
1comptime {
2 const eu: anyerror!u8 = 10;
3 const i: comptime_int = eu;
4 _ = i;
5}
6
7comptime {
8 const op: ?u8 = 10;
9 const i: comptime_int = op;
10 _ = i;
11}
12
13comptime {
14 const op: anyerror!comptime_int = 10;
15 const i: u8 = op;
16 _ = i;
17}
18
19comptime {
20 const op: ?comptime_int = 10;
21 const i: u8 = op;
22 _ = i;
23}
24
25// error
26//
27// :3:29: error: expected type 'comptime_int', found 'anyerror!u8'
28// :9:29: error: expected type 'comptime_int', found '?u8'
29// :15:19: error: expected type 'u8', found 'anyerror!comptime_int'
30// :21:19: error: expected type 'u8', found '?comptime_int'