zig
zig copied to clipboard
compiler crash in build
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
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)
Reduction:
const Foo = enum {
a,
};
test {
const arr = [_]Foo{.a};
_ = arr ++ .{.b};
}
I started investigating this and I think I'm really close to having it fixed. I might be able to finish it tomorrow.
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.
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
@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 {
^~~~
Fixed by #18162 which added test coverage.