Compiler crash with empty slice in comptime generic
dweiller opened this issue · 0 comments
Zig Version
0.12.0 and 0.13.0-dev.46+3648d7df1
Steps to Reproduce and Observed Behavior
I haven't yet been able to make a minimal repro, but setting up a project with the following reproduces it.
build.zig.zon:
.{
.name = "zig-bug",
.version = "0.0.0",
.dependencies = .{
.zli = .{
.url = "https://github.com/dweiller/zli/archive/cbb288b2129ab5ec8181d55cc40dd02371ef5d2b.tar.gz",
.hash = "1220d7b865aa88f0f98dd85e3317006aff163fb9c7485d50a326d90b5b6b85c763fd",
},
},
.paths = .{""},
}
build.zig:
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "zig-bug",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("zli", b.dependency("zli", .{}).module("zli"));
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
src/main.zig:
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const parse_result = try Cli.parse(allocator);
switch (parse_result) {
.ok => |params| _ = params,
.err => |err| {
err.renderToStdErr();
std.process.exit(1);
},
}
}
const arg_spec = [_]zli.Arg{};
const version: std.SemanticVersion = .{
.major = 0,
.minor = 0,
.patch = 0,
};
const Cli = zli.CliCommand("buggy", version, .{ .parameters = &arg_spec });
const zli = @import("zli");
const std = @import("std");
This diff avoids the crash:
- const Cli = zli.CliCommand("buggy", version, .{ .parameters = &arg_spec });
+ const Cli = zli.CliCommand("buggy", version, .{});
(note that the default values of the .parameters
field is an empty slice).
I have bisected the crash to commit d0e74ff from #19630.
A debug build of the compiler reports:
error: thread 26925 panic: reached unreachable code
Analyzing /zig-global-cache/zig/p/1220d7b865aa88f0f98dd85e3317006aff163fb9c7485d50a326d90b5b6b85c763fd/src/root.zig: root.zig:CliCommand
%31 = dbg_stmt(6, 5)
%32 = decl_val("checkNameClash") token_offset:15:5 to :15:19
%33 = dbg_stmt(6, 19)
%34 = call(nodiscard .auto, %32, [
{
%35 = dbg_stmt(6, 27)
%36 = field_val(%30, "parameters") node_offset:15:20 to :15:38
%37 = break_inline(%34, %36)
},
{
%38 = dbg_stmt(6, 47)
%39 = field_val(%30, "include_help") node_offset:15:40 to :15:60
%40 = break_inline(%34, %39)
},
{
%41 = dbg_stmt(6, 69)
%42 = field_val(%30, "include_version") node_offset:15:62 to :15:85
%43 = break_inline(%34, %42)
},
]) node_offset:15:5 to :15:86
%44 = dbg_stmt(8, 5)
> %45 = extended(struct_decl(hash(2f03488edf70f049e11a99171a65c4a6) func, { %30, %23, %27 }, auto, {
%46 = declaration('args' line(+8) hash(1d2945674f7572f65a83b8147c0c5e20) value={%47..%59}) node_offset:18:9 to :18:14
%60 = declaration(pub 'ParsedResult' line(+13) hash(36ef7bcac61577fd88901246e9dff81a) value={%61..%67}) node_offset:23:9 to :23:65
%68 = declaration(pub 'Params' line(+14) hash(3625003312157a5b49ab3cbbe721ab7a) value={%69..%71}) node_offset:24:9 to :24:47
%72 = declaration('longest_arg_name' line(+16) hash(b2c32eeafb79828b1d4aae9055886a50) value={%73, %109}) node_offset:26:9 to :26:14
%110 = declaration(pub 'parse' line(+27) hash(9cf3f5dd5feb9c07656303cc5ab34951) value={%113..%159}) node_offset:37:9 to :37:72
%160 = declaration(pub 'parseOrExit' line(+34) hash(51efb330960d110fab034c2668a55eab) value={%163..%230}) node_offset:44:9 to :44:74
%231 = declaration(pub 'parseWithArgs' line(+44) hash(c7b05011c33bc66be7e91c91c1c51af1) value={%234..%523}) node_offset:54:9 to :54:15
}, {}, {}) node_offset:17:12 to :17:18
%524 = restore_err_ret_index_unconditional(.none) node_offset:17:5 to :17:11
%525 = dbg_stmt(8, 5)
%526 = ret_node(%45) node_offset:17:5 to :17:11
For full context, use the command
zig ast-check -t /zig-global-cache/zig/p/1220d7b865aa88f0f98dd85e3317006aff163fb9c7485d50a326d90b5b6b85c763fd/src/root.zig
in src/main.zig: main.zig:Cli
> %85 = field_call(.compile_time, %83, "CliCommand", [
{%86, %87},
{%88, %89},
{%90..%95},
]) node_offset:25:13 to :25:75
in src/main.zig: main.zig:main
> %29 = decl_ref("Cli") token_offset:6:30 to :6:33
in /path/to/zig/lib/std/start.zig: start.zig:callMain
> %1824 = is_non_err(%1823)
in /path/to/zig/lib/std/start.zig: start.zig:callMain
> %1826 = block({%1821..%1825})
in /path/to/zig/lib/std/start.zig: start.zig:callMain
> %1772 = switch_block(%1770,
else => {%1915, %1918},
%1773 => {%1774..%1778},
%1779 => {%1780..%1788},
by_val %1789 => {%1790..%1818},
%1819 => {%1820..%1914})
in /path/to/zig/lib/std/start.zig: start.zig:callMainWithArgs
> %1577 = call(.auto, %1575, [])
in /path/to/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
> %1414 = call(.auto, %1412, [
{%1415},
{%1416},
{%1417},
])
in /path/to/zig/lib/std/start.zig: start.zig:posixCallMainAndExit
> %1411 = field_call(nodiscard .auto, %1409, "exit", [
{%1412..%1418},
])
/path/to/zig/src/type.zig:1039:35: 0x5ff28c6 in abiAlignmentAdvanced (zig)
.eager => unreachable, // struct alignment not resolved
^
/path/to/zig/src/type.zig:904:84: 0x5ff0789 in abiAlignmentAdvanced (zig)
return Type.fromInterned(array_type.child).abiAlignmentAdvanced(mod, strat);
^
/path/to/zig/src/type.zig:851:40: 0x5ff3a49 in abiAlignment (zig)
return (ty.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
^
/path/to/zig/src/Module.zig:655:72: 0x66e9d36 in declPtrType (zig)
.alignment = if (decl.alignment == decl_ty.abiAlignment(zcu))
^
/path/to/zig/src/Value.zig:4003:66: 0x66e9fd4 in ptrType (zig)
inline .eu_payload_ptr, .opt_payload_ptr, .field_ptr, .elem_ptr => |x| x.result_ptr_ty,
^
/path/to/zig/src/Value.zig:4141:68: 0x66ebb1e in pointerDerivationAdvanced (zig)
if (need_child.comptimeOnly(zcu)) {
^
/path/to/zig/src/print_value.zig:288:61: 0x7ef84dd in printPtr__anon_132272 (zig)
try printPtrDerivation(derivation, writer, level, zcu, opt_sema);
^
/path/to/zig/src/print_value.zig:130:25: 0x7c1f101 in print__anon_127410 (zig)
try writer.writeAll("[0..");
^
/path/to/zig/src/print_value.zig:205:26: 0x7ef8fbb in printAggregate__anon_132273 (zig)
}
^
/path/to/zig/src/print_value.zig:155:53: 0x7c1f686 in print__anon_127410 (zig)
.un => |un| {
^
/path/to/zig/src/print_value.zig:32:17: 0x7c1d3ea in format__anon_127409 (zig)
error.OutOfMemory => @panic("OOM"), // We're not allowed to return this from a format function
^
/path/to/zig/lib/std/fmt.zig:1480:26: 0x76df5e0 in format__anon_119546 (zig)
try format_fn(self.data, fmt, options, writer);
^
/path/to/zig/lib/std/fmt.zig:494:32: 0x71d26f2 in formatType__anon_111404 (zig)
return try value.format(actual_fmt, options, writer);
^
/path/to/zig/lib/std/fmt.zig:185:23: 0x74b62e0 in format__anon_116429 (zig)
try formatType(
^
/path/to/zig/lib/std/io/Writer.zig:23:26: 0x6fb9f30 in print__anon_103294 (zig)
return std.fmt.format(self, format, args);
^
/path/to/zig/lib/std/io.zig:324:47: 0x6fb8a86 in createAnonymousDeclTypeNamed (zig)
return @errorCast(self.any().print(format, args));
^
/path/to/zig/src/Sema.zig:2827:65: 0x6af54be in zirStructDecl (zig)
const new_decl_index = try sema.createAnonymousDeclTypeNamed(
^
/path/to/zig/src/Sema.zig:1215:66: 0x6580b6f in analyzeBodyInner (zig)
.struct_decl => try sema.zirStructDecl( block, extended, inst),
^
/path/to/zig/src/Sema.zig:892:26: 0x6578921 in analyzeFnBody (zig)
sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/path/to/zig/src/Sema.zig:7922:35: 0x6beb7ef in analyzeCall (zig)
// a reference to `comptime_allocs` so is not stable across instances of `Sema`.
^
/path/to/zig/src/Sema.zig:7125:43: 0x6a80c0e in zirCall__anon_93540 (zig)
^
/path/to/zig/src/Sema.zig:1015:62: 0x6579d83 in analyzeBodyInner (zig)
.field_call => try sema.zirCall(block, inst, .field),
^
/path/to/zig/src/Sema.zig:910:30: 0x62ad5c7 in analyzeInlineBody (zig)
if (sema.analyzeBodyInner(block, body)) |_| {
^
/path/to/zig/src/Sema.zig:936:39: 0x600918e in resolveInlineBody (zig)
return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
^
/path/to/zig/src/Module.zig:3650:50: 0x600526d in semaDecl (zig)
const result_ref = try sema.resolveInlineBody(&block_scope, decl_bodies.value_body, decl_inst);
^
/path/to/zig/src/Module.zig:3015:32: 0x5de17f1 in ensureDeclAnalyzed (zig)
break :blk mod.semaDecl(decl_index) catch |err| switch (err) {
^
/path/to/zig/src/Sema.zig:31901:27: 0x6000ff9 in ensureDeclAnalyzed (zig)
ip.funcAnalysis(sema.owner_func_index).state = .dependency_failure;
^
/path/to/zig/src/Sema.zig:31946:32: 0x6bee05a in analyzeDeclRefInner (zig)
.is_const = if (decl_val.getVariable(mod)) |variable| variable.is_const else true,
^
/path/to/zig/src/Sema.zig:31937:36: 0x66a97ce in analyzeDeclRef (zig)
.func => |func| func.owner_decl,
^
/path/to/zig/src/Sema.zig:6795:31: 0x6a831ad in zirDeclRef (zig)
^
/path/to/zig/src/Sema.zig:1022:65: 0x657a24b in analyzeBodyInner (zig)
.decl_ref => try sema.zirDeclRef(block, inst),
^
/path/to/zig/src/Sema.zig:892:26: 0x6578921 in analyzeFnBody (zig)
sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/path/to/zig/src/Module.zig:4633:23: 0x626cafb in analyzeFnBody (zig)
sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
^
/path/to/zig/src/Module.zig:3143:32: 0x5fe10d8 in ensureFuncBodyAnalyzed (zig)
var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
^
/path/to/zig/src/Sema.zig:31914:31: 0x6bf8edd in ensureFuncBodyAnalyzed (zig)
.val = if (opt_val) |val| (try mod.getCoerced(
^
/path/to/zig/src/Sema.zig:35927:40: 0x66944bd in resolveInferredErrorSet (zig)
) CompileError!void {
^
/path/to/zig/src/Sema.zig:32275:69: 0x6b3779d in analyzeIsNonErrComptimeOnly (zig)
return .bool_true;
^
/path/to/zig/src/Sema.zig:32304:56: 0x6f54659 in analyzeIsNonErr (zig)
const result = try sema.analyzePtrIsNonErrComptimeOnly(block, src, operand);
^
/path/to/zig/src/Sema.zig:19189:32: 0x6a8e6df in zirIsNonErr (zig)
^
/path/to/zig/src/Sema.zig:1056:66: 0x657b726 in analyzeBodyInner (zig)
.is_non_err => try sema.zirIsNonErr(block, inst),
^
/path/to/zig/src/Sema.zig:6165:34: 0x6f7de7b in resolveBlockBody (zig)
.body_len = @intCast(child_block.instructions.items.len),
^
/path/to/zig/src/Sema.zig:6142:33: 0x6b3a62e in zirBlock (zig)
merges: *Block.Merges,
^
/path/to/zig/src/Sema.zig:1559:49: 0x658815f in analyzeBodyInner (zig)
break :blk try sema.zirBlock(block, inst, tags[@intFromEnum(inst)] == .block_comptime);
^
/path/to/zig/src/Sema.zig:6165:34: 0x6f7de7b in resolveBlockBody (zig)
.body_len = @intCast(child_block.instructions.items.len),
^
/path/to/zig/src/Sema.zig:11017:45: 0x6f74b40 in resolveProngComptime (zig)
return .unreachable_value;
^
/path/to/zig/src/Sema.zig:13156:48: 0x6f733a9 in resolveSwitchComptime (zig)
var multi_i: usize = 0;
^
/path/to/zig/src/Sema.zig:12395:37: 0x6a9ea00 in zirSwitchBlock (zig)
^
/path/to/zig/src/Sema.zig:1079:69: 0x657c552 in analyzeBodyInner (zig)
.switch_block => try sema.zirSwitchBlock(block, inst, false),
^
/path/to/zig/src/Sema.zig:892:26: 0x6578921 in analyzeFnBody (zig)
sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/path/to/zig/src/Sema.zig:7922:35: 0x6beb7ef in analyzeCall (zig)
// a reference to `comptime_allocs` so is not stable across instances of `Sema`.
^
/path/to/zig/src/Sema.zig:7125:43: 0x6a7f99e in zirCall__anon_93539 (zig)
^
/path/to/zig/src/Sema.zig:1014:62: 0x6579ce6 in analyzeBodyInner (zig)
.call => try sema.zirCall(block, inst, .direct),
^
/path/to/zig/src/Sema.zig:892:26: 0x6578921 in analyzeFnBody (zig)
sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/path/to/zig/src/Sema.zig:7922:35: 0x6beb7ef in analyzeCall (zig)
// a reference to `comptime_allocs` so is not stable across instances of `Sema`.
^
/path/to/zig/src/Sema.zig:7125:43: 0x6a7f99e in zirCall__anon_93539 (zig)
^
/path/to/zig/src/Sema.zig:1014:62: 0x6579ce6 in analyzeBodyInner (zig)
.call => try sema.zirCall(block, inst, .direct),
^
/path/to/zig/src/Sema.zig:910:30: 0x62ad5c7 in analyzeInlineBody (zig)
if (sema.analyzeBodyInner(block, body)) |_| {
^
/path/to/zig/src/Sema.zig:936:39: 0x600918e in resolveInlineBody (zig)
return (try sema.analyzeInlineBody(block, body, break_target)) orelse .unreachable_value;
^
/path/to/zig/src/Sema.zig:7414:65: 0x715c437 in analyzeArg (zig)
switch (param_ty.toIntern()) {
^
/path/to/zig/src/Sema.zig:7977:49: 0x6bec57e in analyzeCall (zig)
if (mod.intern_pool.isFuncBody(func_val.toIntern())) {
^
/path/to/zig/src/Sema.zig:7125:43: 0x6a80c0e in zirCall__anon_93540 (zig)
^
/path/to/zig/src/Sema.zig:1015:62: 0x6579d83 in analyzeBodyInner (zig)
.field_call => try sema.zirCall(block, inst, .field),
^
/path/to/zig/src/Sema.zig:892:26: 0x6578921 in analyzeFnBody (zig)
sema.analyzeBodyInner(block, body) catch |err| switch (err) {
^
/path/to/zig/src/Module.zig:4633:23: 0x626cafb in analyzeFnBody (zig)
sema.analyzeFnBody(&inner_block, fn_info.body) catch |err| switch (err) {
^
/path/to/zig/src/Module.zig:3143:32: 0x5fe10d8 in ensureFuncBodyAnalyzed (zig)
var air = zcu.analyzeFnBody(func_index, sema_arena) catch |err| switch (err) {
^
/path/to/zig/src/Compilation.zig:3419:42: 0x5fdede2 in processOneJob (zig)
module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
^
/path/to/zig/src/Compilation.zig:3359:30: 0x5e0db3a in performAllTheWork (zig)
try processOneJob(comp, work_item, main_progress_node);
^
/path/to/zig/src/Compilation.zig:2132:31: 0x5e09072 in update (zig)
try comp.performAllTheWork(main_progress_node);
^
/path/to/zig/src/main.zig:4085:36: 0x5e83f4c in serve (zig)
continue;
^
/path/to/zig/src/main.zig:3362:22: 0x5ea2681 in buildOutputType (zig)
if (show_builtin) {
^
/path/to/zig/src/main.zig:260:31: 0x5ceb331 in mainArgs (zig)
return buildOutputType(gpa, arena, args, .{ .build = .Exe });
^
/path/to/zig/src/main.zig:206:20: 0x5ce82c5 in main (zig)
return mainArgs(gpa, arena, args);
^
/path/to/zig/lib/std/start.zig:511:37: 0x5ce7d5e in main (zig)
const result = root.main() catch |err| {
^
../sysdeps/nptl/libc_start_call_main.h:58:16: 0x7f10145aad8f in __libc_start_call_main (../sysdeps/x86/libc-start.c)
../csu/libc-start.c:392:3: 0x7f10145aae3f in __libc_start_main_impl (../sysdeps/x86/libc-start.c)
???:?:?: 0x5ce79a4 in ??? (???)
???:?:?: 0x0 in ??? (???)
Expected Behavior
The compiler shouldn't crash - the stack trace makes it look like it's hitting unreachable, but it also looks like the trace isn't printing quite correctly (arrows pointing to odd columns, some arrows don't have a line their pointing to etc), so not sure how much it can be trusted. The stack trace was generated by a debug build of zig version 0.12.1-dev.17+600b65282
.