Skip to content

Conversation

@rmehri01
Copy link

Fixes #25645

Besides the case reported in the issue, this also seems to occur with optionals. It seems like in trying to produce a nice error message for converting E!T/?T to T, we try to coerce comptime_int to int despite the source value being an error union type and not an integer.

To prevent this I think we can just not pass the source value to coerceInMemoryAllowed since the nice error message doesn't apply to this case anyways.

Example compiler crash context
Analyzing 'test.zig'
      %16 = ref(@zero) token_offset:6:9 to :6:10
      %17 = load(%16) node_offset:6:9 to :6:15
      %18 = extended(inplace_arith_result_ty(%17, add_eq))
    > %19 = as_node(%18, %11) node_offset:6:14 to :6:15
      %20 = add(%17, %19) node_offset:6:9 to :6:15
      %21 = store_node(%16, %20) node_offset:6:9 to :6:15
      %22 = break_inline(%15, @void_value)
    For full context, use the command
      stage4/bin/zig ast-check -t test.zig

  in test.zig
    > %15 = block_comptime(reason=comptime_keyword, {%16..%22}) node_offset:5:5 to :5:13
  in /home/projects/zig/lib/std/start.zig
    > %2072 = is_non_err(%2071) 
  in /home/projects/zig/lib/std/start.zig
    > %2074 = block({%2069..%2073}) 
  in /home/projects/zig/lib/std/start.zig
    > %2036 = switch_block(%2031,
        else => {%2054..%2179},
        @void_type => {%2037..%2045},
        @noreturn_type, @u8_type => {%2046..%2053}) 
  in /home/projects/zig/lib/std/start.zig
    > %1831 = call(.auto, %1829, []) 
  in /home/projects/zig/lib/std/start.zig
    > %1650 = call(.auto, %1648, [
        {%1651},
        {%1652},
        {%1653},
      ]) 
  in /home/projects/zig/lib/std/start.zig
    > %1647 = field_call(nodiscard .auto, %1645, "exit", [
        {%1648..%1654},
      ]) 

thread 1111402 panic: reached unreachable code
/home/projects/zig/src/Sema.zig:36809:21: 0x402bc70 in intFitsInType (main.zig)
            else => unreachable,
                    ^
/home/projects/zig/src/Sema.zig:29641:41: 0x4007c04 in coerceInMemoryAllowed (main.zig)
            if (!(try sema.intFitsInType(val, dest_ty, null))) {
                                        ^
/home/projects/zig/src/Sema.zig:29164:44: 0x370ea0d in coerceExtra (main.zig)
            (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(zcu), dest_ty, false, target, dest_ty_src, inst_src, null)) == .ok)
                                           ^
/home/projects/zig/src/Sema.zig:9650:28: 0x45f6507 in analyzeAs (main.zig)
    return sema.coerceExtra(block, dest_ty, operand, src, .{ .is_ret = is_ret, .no_cast_to_comptime_int = no_cast_to_comptime_int }) catch |err| switch (err) {
                           ^
/home/projects/zig/src/Sema.zig:9615:26: 0x3e9b587 in zirAsNode (main.zig)
    return sema.analyzeAs(block, src, extra.dest_type, extra.operand, false);
                         ^
/home/projects/zig/src/Sema.zig:1171:64: 0x36acc90 in analyzeBodyInner (main.zig)
            .as_node                      => try sema.zirAsNode(block, inst),
                                                               ^
/home/projects/zig/src/Sema.zig:1062:30: 0x36e9082 in analyzeInlineBody (main.zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/projects/zig/src/Sema.zig:1095:39: 0x2d7fd02 in resolveInlineBody (main.zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/projects/zig/src/Sema.zig:1746:58: 0x36bb5f8 in analyzeBodyInner (main.zig)
                const result = try sema.resolveInlineBody(&child_block, block_body, inst);
                                                         ^
/home/projects/zig/src/Sema.zig:1044:26: 0x2d78d71 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/projects/zig/src/Zcu/PerThread.zig:2951:23: 0x2d7c853 in analyzeFnBodyInner (main.zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^
/home/projects/zig/src/Zcu/PerThread.zig:1727:40: 0x27f5e2c in analyzeFuncBody (main.zig)
    var air = try pt.analyzeFnBodyInner(func_index);
                                       ^
/home/projects/zig/src/Zcu/PerThread.zig:1647:66: 0x2326802 in ensureFuncBodyUpToDate (main.zig)
    const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index)) |result|
                                                                 ^
/home/projects/zig/src/Sema.zig:35090:38: 0x4016385 in resolveInferredErrorSet (main.zig)
        try pt.ensureFuncBodyUpToDate(orig_func_index);
                                     ^
/home/projects/zig/src/Sema.zig:31762:69: 0x3fe95a3 in analyzeIsNonErrComptimeOnly (main.zig)
                const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty);
                                                                    ^
/home/projects/zig/src/Sema.zig:31784:56: 0x463a3af in analyzeIsNonErr (main.zig)
    const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
                                                       ^
/home/projects/zig/src/Sema.zig:18337:32: 0x3ec7e37 in zirIsNonErr (main.zig)
    return sema.analyzeIsNonErr(block, src, operand);
                               ^
/home/projects/zig/src/Sema.zig:1226:66: 0x36af3f3 in analyzeBodyInner (main.zig)
            .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                                 ^
/home/projects/zig/src/Sema.zig:5909:34: 0x4672fbd in resolveBlockBody (main.zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/projects/zig/src/Sema.zig:5886:33: 0x3fdc717 in zirBlock (main.zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/projects/zig/src/Sema.zig:1722:37: 0x36bb160 in analyzeBodyInner (main.zig)
            } else try sema.zirBlock(block, inst),
                                    ^
/home/projects/zig/src/Sema.zig:5909:34: 0x4672fbd in resolveBlockBody (main.zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/projects/zig/src/Sema.zig:10428:45: 0x4662e9f in resolveProngComptime (main.zig)
                return sema.resolveBlockBody(spa.parent_block, src, child_block, prong_body, spa.switch_block_inst, merges);
                                            ^
/home/projects/zig/src/Sema.zig:13170:36: 0x4676094 in resolveSwitchComptime (main.zig)
    return spa.resolveProngComptime(
                                   ^
/home/projects/zig/src/Sema.zig:12974:34: 0x4661c0d in resolveSwitchComptimeLoop (main.zig)
        if (resolveSwitchComptime(
                                 ^
/home/projects/zig/src/Sema.zig:12033:49: 0x3ee9397 in zirSwitchBlock (main.zig)
                return resolveSwitchComptimeLoop(
                                                ^
/home/projects/zig/src/Sema.zig:1250:69: 0x36b04e9 in analyzeBodyInner (main.zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                                                    ^
/home/projects/zig/src/Sema.zig:1044:26: 0x2d78d71 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/projects/zig/src/Sema.zig:7868:27: 0x460ee99 in analyzeCall (main.zig)
        sema.analyzeFnBody(&child_block, fn_zir_info.body) catch |err| switch (err) {
                          ^
/home/projects/zig/src/Sema.zig:6827:43: 0x3eabba3 in zirCall__anon_720250 (main.zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/projects/zig/src/Sema.zig:1182:62: 0x36ad45f in analyzeBodyInner (main.zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/projects/zig/src/Sema.zig:1044:26: 0x2d78d71 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/projects/zig/src/Sema.zig:7868:27: 0x460ee99 in analyzeCall (main.zig)
        sema.analyzeFnBody(&child_block, fn_zir_info.body) catch |err| switch (err) {
                          ^
/home/projects/zig/src/Sema.zig:6827:43: 0x3eabba3 in zirCall__anon_720250 (main.zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/projects/zig/src/Sema.zig:1182:62: 0x36ad45f in analyzeBodyInner (main.zig)
            .call                         => try sema.zirCall(block, inst, .direct),
                                                             ^
/home/projects/zig/src/Sema.zig:1062:30: 0x36e9082 in analyzeInlineBody (main.zig)
    if (sema.analyzeBodyInner(block, body)) |_| {
                             ^
/home/projects/zig/src/Sema.zig:1095:39: 0x2d7fd02 in resolveInlineBody (main.zig)
    return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
                                      ^
/home/projects/zig/src/Sema.zig:7126:65: 0x4e50a69 in analyzeArg (main.zig)
                const uncoerced_arg = try sema.resolveInlineBody(block, arg_body, zir_call.call_inst);
                                                                ^
/home/projects/zig/src/Sema.zig:7363:41: 0x4603fb9 in analyzeCall (main.zig)
        arg.* = try args_info.analyzeArg(sema, block, arg_idx, param_ty, func_ty_info, callee, maybe_func_inst);
                                        ^
/home/projects/zig/src/Sema.zig:6827:43: 0x3ead9d4 in zirCall__anon_720252 (main.zig)
    const call_inst = try sema.analyzeCall(block, func, func_ty, callee_src, call_src, modifier, ensure_result_used, args_info, call_dbg_node, .call);
                                          ^
/home/projects/zig/src/Sema.zig:1183:62: 0x36ad514 in analyzeBodyInner (main.zig)
            .field_call                   => try sema.zirCall(block, inst, .field),
                                                             ^
/home/projects/zig/src/Sema.zig:1044:26: 0x2d78d71 in analyzeFnBody (main.zig)
    sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                         ^
/home/projects/zig/src/Zcu/PerThread.zig:2951:23: 0x2d7c853 in analyzeFnBodyInner (main.zig)
    sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
                      ^
/home/projects/zig/src/Zcu/PerThread.zig:1727:40: 0x27f5e2c in analyzeFuncBody (main.zig)
    var air = try pt.analyzeFnBodyInner(func_index);
                                       ^
/home/projects/zig/src/Zcu/PerThread.zig:1647:66: 0x2326802 in ensureFuncBodyUpToDate (main.zig)
    const ies_outdated, const new_failed = if (pt.analyzeFuncBody(func_index)) |result|
                                                                 ^
/home/projects/zig/src/Compilation.zig:5147:38: 0x2127833 in processOneJob (main.zig)
            pt.ensureFuncBodyUpToDate(func) catch |err| switch (err) {
                                     ^
/home/projects/zig/src/Compilation.zig:5017:30: 0x1fc1f97 in performAllTheWork (main.zig)
            try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job);
                             ^
/home/projects/zig/src/Compilation.zig:3094:31: 0x1ed6ac8 in update (main.zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/projects/zig/src/main.zig:4504:20: 0x1ee81cb in updateModule (main.zig)
    try comp.update(prog_node);
                   ^
/home/projects/zig/src/main.zig:3597:21: 0x1df06de in buildOutputType (main.zig)
        updateModule(comp, color, root_prog_node) catch |err| switch (err) {
                    ^
/home/projects/zig/src/main.zig:267:31: 0x1e367f6 in mainArgs (main.zig)
        return buildOutputType(gpa, arena, args, .run);
                              ^
/home/projects/zig/src/main.zig:204:20: 0x1d9b892 in main (main.zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/projects/zig/lib/std/start.zig:657:37: 0x1d99c37 in callMain (std.zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7f667982a4d7 in __libc_start_call_main (/nix/store/qhw0sp183mqd04x5jp75981kwya64npv-glibc-2.40-66/lib/libc.so.6)
???:?:?: 0x7f667982a59a in __libc_start_main_alias_2 (/nix/store/qhw0sp183mqd04x5jp75981kwya64npv-glibc-2.40-66/lib/libc.so.6)
???:?:?: 0x607b964 in ??? (???)
fish: Job 2, 'stage4/bin/zig run test.zig' terminated by signal SIGABRT (Abort)

@rmehri01 rmehri01 force-pushed the fix_comptime_int_coercion_crash branch from 7123214 to 964a3f5 Compare October 24, 2025 03:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Compiler segfaults when trying to increment a constant at comptime

2 participants