From 20befa4e64f1654fa3c69a0e7b0b194193c2ab27 Mon Sep 17 00:00:00 2001 From: Rue04 Date: Wed, 15 Jul 2026 23:04:54 +0200 Subject: [PATCH] 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 --- src/Sema.zig | 4 +-- ...optional_containing_or_to_comptime_int.zig | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 test/cases/compile_errors/coercion_from_eu_or_optional_containing_or_to_comptime_int.zig diff --git a/src/Sema.zig b/src/Sema.zig index 9fe0f32b05d663463bc8abd04cf213d456f1287f..4b29027056be47f0bccaa0250f7b30a3a8980667 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -28356,7 +28356,7 @@ fn coerceExtra( // E!T to T if (inst_ty.zigTypeTag(zcu) == .error_union and - (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, null)) == .ok) + (try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty.errorUnionPayload(zcu), false, target, dest_ty_src, inst_src, null)) == .ok) { try sema.errNote(inst_src, msg, "cannot convert error union to payload type", .{}); try sema.errNote(inst_src, msg, "consider using 'try', 'catch', or 'if'", .{}); @@ -28364,7 +28364,7 @@ fn coerceExtra( // ?T to T if (inst_ty.zigTypeTag(zcu) == .optional and - (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src, null)) == .ok) + (try sema.coerceInMemoryAllowed(block, dest_ty, inst_ty.optionalChild(zcu), false, target, dest_ty_src, inst_src, null)) == .ok) { try sema.errNote(inst_src, msg, "cannot convert optional to payload type", .{}); try sema.errNote(inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{}); diff --git a/test/cases/compile_errors/coercion_from_eu_or_optional_containing_or_to_comptime_int.zig b/test/cases/compile_errors/coercion_from_eu_or_optional_containing_or_to_comptime_int.zig new file mode 100644 index 0000000000000000000000000000000000000000..ecdbb5df9d7bf8a5315778895134dc022cb150d6 --- /dev/null +++ b/test/cases/compile_errors/coercion_from_eu_or_optional_containing_or_to_comptime_int.zig @@ -0,0 +1,30 @@ +comptime { + const eu: anyerror!u8 = 10; + const i: comptime_int = eu; + _ = i; +} + +comptime { + const op: ?u8 = 10; + const i: comptime_int = op; + _ = i; +} + +comptime { + const op: anyerror!comptime_int = 10; + const i: u8 = op; + _ = i; +} + +comptime { + const op: ?comptime_int = 10; + const i: u8 = op; + _ = i; +} + +// error +// +// :3:29: error: expected type 'comptime_int', found 'anyerror!u8' +// :9:29: error: expected type 'comptime_int', found '?u8' +// :15:19: error: expected type 'u8', found 'anyerror!comptime_int' +// :21:19: error: expected type 'u8', found '?comptime_int' -- 2.54.0