zig icon indicating copy to clipboard operation
zig copied to clipboard

compiler crash in build

Open davidgm94 opened this issue 1 year ago • 2 comments

Zig Version

0.11.0-dev.3658+5d9e8f27d

Steps to Reproduce and Observed Behavior

Edit: I posted a reduction a couple of comments below:

const Foo = enum {
    a,
};
test {
    const arr = [_]Foo{.a};
    _ = arr ++ .{.b};
}
git clone https://github.com/davidgm94/rise.git
cd rise
zig build

Log:

zig build                                                           [Last command returned (130)] [david@MacBook-Air] [8:43:00]
Semantic Analysis [1389] thread 10984635 panic: zig compiler bug: NeededSourceLocation
Analyzing /Users/david/dev/zig/lib/std/Build.zig: Build.zig:runBuild__anon_6808
      %9724 = dbg_block_begin()
      %9725 = dbg_stmt(4, 24)
      %9726 = ref(%9695) 
      %9727 = dbg_stmt(4, 37)
      %9728 = dbg_stmt(4, 43)
      %9729 = field_call(.auto, %9726, "build", [
        {
          %9730 = break_inline(%9729, %9694)
        },
      ]) 
    > %9731 = try(%9729, {
        %9732 = err_union_code(%9729) 
        %9733 = dbg_stmt(4, 24)
        %9734 = ret_node(%9732) 
      }) 
      %9735 = dbg_block_end()
      %9736 = break(%9713, %9731)
    For full context, use the command
      zig ast-check -t /Users/david/dev/zig/lib/std/Build.zig

  in /Users/david/dev/zig/lib/std/Build.zig: Build.zig:runBuild__anon_6808
    > %9713 = switch_block(%9711,
        else => {%9737..%9741},
        %9714 => {%9715..%9722},
        %9723 => {%9724..%9736}) 
  in /Users/david/dev/zig/lib/std/Build.zig: Build.zig:runBuild__anon_6808
    > %9698 = block({%9699..%9745}) 

/Users/david/dev/zig/src/Sema.zig:2326:13: 0x102a82f3b in failWithOwnedErrorMsg (zig)
            return error.NeededSourceLocation;
            ^
/Users/david/dev/zig/src/Sema.zig:27112:21: 0x102c7800b in coerceExtra (zig)
                    return sema.failWithOwnedErrorMsg(msg);
                    ^
/Users/david/dev/zig/src/Sema.zig:26566:21: 0x102a8e503 in coerce (zig)
        else => |e| return e,
                    ^
/Users/david/dev/zig/src/Sema.zig:13356:47: 0x102ea65cb in zirArrayCat (zig)
                const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded);
                                              ^
/Users/david/dev/zig/src/Sema.zig:927:46: 0x102c50c0b in analyzeBodyInner (zig)
            .array_cat                    => try sema.zirArrayCat(block, inst),
                                             ^
/Users/david/dev/zig/src/Sema.zig:5678:25: 0x10347a22f in resolveBlockBody (zig)
            else => |e| return e,
                        ^
/Users/david/dev/zig/src/Sema.zig:5644:5: 0x102f771f3 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
    ^
/Users/david/dev/zig/src/Sema.zig:1486:32: 0x102c63153 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                               ^
/Users/david/dev/zig/src/Sema.zig:814:21: 0x1034789a7 in analyzeBodyRuntimeBreak (zig)
        else => |e| return e,
                    ^
/Users/david/dev/zig/src/Sema.zig:10212:17: 0x10341b073 in analyzeProngRuntime (zig)
                return sema.analyzeBodyRuntimeBreak(case_block, prong_body);
                ^
/Users/david/dev/zig/src/Sema.zig:11555:13: 0x102ed57d3 in zirSwitchBlock (zig)
            try spa.analyzeProngRuntime(
            ^
/Users/david/dev/zig/src/Sema.zig:1010:46: 0x102c54b7b in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                             ^
/Users/david/dev/zig/src/Sema.zig:814:21: 0x1034789a7 in analyzeBodyRuntimeBreak (zig)
        else => |e| return e,
                    ^
/Users/david/dev/zig/src/Sema.zig:10212:17: 0x10341b073 in analyzeProngRuntime (zig)
                return sema.analyzeBodyRuntimeBreak(case_block, prong_body);
                ^
/Users/david/dev/zig/src/Sema.zig:11555:13: 0x102ed57d3 in zirSwitchBlock (zig)
            try spa.analyzeProngRuntime(
            ^
/Users/david/dev/zig/src/Sema.zig:1010:46: 0x102c54b7b in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                             ^
/Users/david/dev/zig/src/Sema.zig:814:21: 0x1034789a7 in analyzeBodyRuntimeBreak (zig)
        else => |e| return e,
                    ^
/Users/david/dev/zig/src/Sema.zig:10212:17: 0x10341b073 in analyzeProngRuntime (zig)
                return sema.analyzeBodyRuntimeBreak(case_block, prong_body);
                ^
/Users/david/dev/zig/src/Sema.zig:11555:13: 0x102ed57d3 in zirSwitchBlock (zig)
            try spa.analyzeProngRuntime(
            ^
/Users/david/dev/zig/src/Sema.zig:1010:46: 0x102c54b7b in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                             ^
/Users/david/dev/zig/src/Sema.zig:5678:25: 0x10347a22f in resolveBlockBody (zig)
            else => |e| return e,
                        ^
/Users/david/dev/zig/src/Sema.zig:5644:5: 0x102f771f3 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
    ^
/Users/david/dev/zig/src/Sema.zig:1486:32: 0x102c63153 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                               ^
/Users/david/dev/zig/src/Sema.zig:814:21: 0x1034789a7 in analyzeBodyRuntimeBreak (zig)
        else => |e| return e,
                    ^
/Users/david/dev/zig/src/Sema.zig:17961:5: 0x102f71ffb in zirCondbr (zig)
    try sema.analyzeBodyRuntimeBreak(&sub_block, then_body);
    ^
/Users/david/dev/zig/src/Sema.zig:1751:5: 0x102c63b5b in analyzeBodyInner (zig)
    return result;
    ^
/Users/david/dev/zig/src/Sema.zig:5678:25: 0x10347a22f in resolveBlockBody (zig)
            else => |e| return e,
                        ^
/Users/david/dev/zig/src/Sema.zig:5644:5: 0x102f771f3 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
    ^
/Users/david/dev/zig/src/Sema.zig:1486:32: 0x102c63153 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                               ^
/Users/david/dev/zig/src/Sema.zig:825:21: 0x102e56537 in analyzeBody (zig)
        else => |e| return e,
                    ^
/Users/david/dev/zig/src/Sema.zig:5442:5: 0x102f6f9c3 in zirLoop (zig)
    try sema.analyzeBody(&loop_block, body);
    ^
/Users/david/dev/zig/src/Sema.zig:1471:52: 0x102c5f77f in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirLoop(block, inst);
                                                   ^
(52 additional stack frames skipped...)
/Users/david/dev/zig/src/Module.zig:5568:39: 0x102c3263f in analyzeFnBody (zig)
        error.NeededSourceLocation => @panic("zig compiler bug: NeededSourceLocation"),
                                      ^
/Users/david/dev/zig/src/Module.zig:4164:40: 0x102a741ef in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                                       ^
/Users/david/dev/zig/src/Sema.zig:30221:36: 0x10349fb0f in ensureFuncBodyAnalyzed (zig)
    sema.mod.ensureFuncBodyAnalyzed(func) catch |err| {
                                   ^
/Users/david/dev/zig/src/Sema.zig:33947:40: 0x102fa3e1b in resolveInferredErrorSet (zig)
        try sema.ensureFuncBodyAnalyzed(ies.func);
                                       ^
/Users/david/dev/zig/src/Sema.zig:30546:53: 0x102f73f47 in analyzeIsNonErrComptimeOnly (zig)
                    try sema.resolveInferredErrorSet(block, src, ies_index);
                                                    ^
/Users/david/dev/zig/src/Sema.zig:18013:60: 0x102f72dab in zirTry (zig)
    const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union);
                                                           ^
/Users/david/dev/zig/src/Sema.zig:1641:67: 0x102c61543 in analyzeBodyInner (zig)
                if (!block.is_comptime) break :blk try sema.zirTry(block, inst);
                                                                  ^
/Users/david/dev/zig/src/Sema.zig:5661:34: 0x10347a0d3 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/Users/david/dev/zig/src/Sema.zig:10156:45: 0x10341a357 in resolveProngComptime (zig)
                return sema.resolveBlockBody(spa.parent_block, src, child_block, prong_body, spa.switch_block_inst, merges);
                                            ^
/Users/david/dev/zig/src/Sema.zig:11381:52: 0x102ed2af3 in zirSwitchBlock (zig)
                    return spa.resolveProngComptime(
                                                   ^
/Users/david/dev/zig/src/Sema.zig:1010:69: 0x102c54b2b in analyzeBodyInner (zig)
            .switch_block                 => try sema.zirSwitchBlock(block, inst, false),
                                                                    ^
/Users/david/dev/zig/src/Sema.zig:5661:34: 0x10347a0d3 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/Users/david/dev/zig/src/Sema.zig:5644:33: 0x102f77177 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/Users/david/dev/zig/src/Sema.zig:1486:49: 0x102c63103 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
/Users/david/dev/zig/src/Sema.zig:823:30: 0x102e564f3 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/Users/david/dev/zig/src/Module.zig:5566:21: 0x102c32533 in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
/Users/david/dev/zig/src/Module.zig:4164:40: 0x102a741ef in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
                                       ^
/Users/david/dev/zig/src/Compilation.zig:3143:42: 0x102a723d3 in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/Users/david/dev/zig/src/Compilation.zig:3080:30: 0x10290c9af in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/Users/david/dev/zig/src/Compilation.zig:2029:31: 0x1029090fb in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/Users/david/dev/zig/src/main.zig:3840:24: 0x102936803 in updateModule (zig)
        try comp.update(main_progress_node);
                       ^
/Users/david/dev/zig/src/main.zig:4479:21: 0x1027c616f in cmdBuild (zig)
        updateModule(comp) catch |err| switch (err) {
                    ^
/Users/david/dev/zig/src/main.zig:285:24: 0x10276d5e3 in mainArgs (zig)
        return cmdBuild(gpa, arena, cmd_args);
                       ^
/Users/david/dev/zig/src/main.zig:213:20: 0x10276a79f in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/Users/david/dev/zig/lib/std/start.zig:609:37: 0x10276a39b in main (zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x1894c7e4f in ??? (???)
???:?:?: 0x903c7fffffffffff in ??? (???)
zsh: abort      zig build

Expected Behavior

Build or error

davidgm94 avatar Jun 16 '23 14:06 davidgm94

If it serves to you this all happened when concatenating an enum array with one-element tuple with enum literal that does not belong to the enum (the enum doesn't have a field by that name)

davidgm94 avatar Jun 16 '23 14:06 davidgm94

Reduction:

const Foo = enum {
    a,
};
test {
    const arr = [_]Foo{.a};
    _ = arr ++ .{.b};
}

davidgm94 avatar Jun 16 '23 16:06 davidgm94

I started investigating this and I think I'm really close to having it fixed. I might be able to finish it tomorrow.

ghost avatar Jun 17 '23 09:06 ghost

With this patch:

diff --git a/src/Sema.zig b/src/Sema.zig
index f703c6154..c41c118b6 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -13353,7 +13353,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
                 const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable";
                 const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(mod, rhs_elem_i) else elem_default_val;
                 const elem_val_inst = try sema.addConstant(elem_ty, elem_val);
-                const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded);
+                const coerced_elem_val_inst = sema.coerce(block, resolved_elem_ty, elem_val_inst, rhs_src);
                 const coerced_elem_val = try sema.resolveConstMaybeUndefVal(block, .unneeded, coerced_elem_val_inst, "");
                 element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod);
             }

It generates an error saying that Foo doesn't have a field called b, but it points to all of .{.b} instead of just .b. For the life of me, I can't figure out how to get the proper source location here.

ghost avatar Jun 18 '23 00:06 ghost

Here is a complete test case:

export fn a() void {
    const Foo = enum {
        a,
    };
    const arr = [_]Foo{.a};
    _ = arr ++ .{.b};
}
export fn b() void {
    const Foo = enum {
        a,
    };
    const arr = [_]Foo{.a};
    _ = .{.b} ++ arr;
}

export fn c() void {
    comptime var things: []const i32 = &.{};
    things = things ++ .{&1};
}
export fn d() void {
    comptime var things: []const i32 = &.{};
    things = .{&1} ++ things;
}

See also: https://github.com/ziglang/zig/issues/16509

wooster0 avatar Jul 23 '23 18:07 wooster0

@Vexu The compiler works correctly with 0.12.0-dev.2341+92211135 on Linux:

test.zig:7:19: error: no field named 'b' in enum 'test.Foo'
    _ = arr ++ .{.b};
                 ~^
test.zig:1:13: note: enum declared here
const Foo = enum {
            ^~~~

perillo avatar Jan 29 '24 20:01 perillo

Fixed by #18162 which added test coverage.

Vexu avatar Jan 30 '24 20:01 Vexu