Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler crash when assigning to comptime var array element at runtime #22186

Open
sin-ack opened this issue Dec 8, 2024 · 3 comments
Open
Labels
bug Observed behavior contradicts documented or intended behavior

Comments

@sin-ack
Copy link
Contributor

sin-ack commented Dec 8, 2024

Zig Version

0.14.0-dev.2367+aa7d13846

Steps to Reproduce and Observed Behavior

zig reduced example:

pub fn CombinationIterator(comptime T: type, comptime count: usize) type {
    return struct {
        items: []const Item,
        indices: [count]usize,

        pub const Item = T;
        const Iterator = @This();

        pub fn init(items: []const Item) !Iterator {
            comptime var indices: [count]usize = undefined;
            for (0..count) |i| {
                indices[i] = i;
            }

            return .{ .items = items, .indices = indices };
        }
    };
}

pub fn main() !void {
    const items = [_]u64{ 1, 2, 3 };
    try CombinationIterator(u64, 3).init(&items);
}

Removing comptime from comptime var makes it work.

Stack trace
» zig-debug run result.zig
thread 23863 panic: reached unreachable code
/home/agni/zig/compiler/src/codegen/llvm.zig:4579:60: 0x1f65be7 in lowerPtr (zig)
            .arr_elem, .comptime_field, .comptime_alloc => unreachable,
                                                           ^
/home/agni/zig/compiler/src/codegen/llvm.zig:4120:35: 0x1c9b315 in lowerValue (zig)
            .ptr => try o.lowerPtr(arg_val, 0),
                                  ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5123:42: 0x2f53167 in resolveValue (zig)
        const llvm_val = try o.lowerValue(val.toIntern());
                                         ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5114:47: 0x2f52ef3 in resolveInst (zig)
        const llvm_val = try self.resolveValue((try self.air.value(inst, self.ng.object.pt)).?);
                                              ^
/home/agni/zig/compiler/src/codegen/llvm.zig:7246:46: 0x2fb61c6 in airPtrElemPtr (zig)
        const base_ptr = try self.resolveInst(bin_op.lhs);
                                             ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5370:62: 0x2b119fb in genBody (zig)
                .ptr_elem_ptr       => try self.airPtrElemPtr(inst),
                                                             ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5546:25: 0x2f8149d in genBodyDebugScope (zig)
        try self.genBody(body, coverage_point);
                        ^
/home/agni/zig/compiler/src/codegen/llvm.zig:6577:35: 0x2fc64ac in airCondBr (zig)
        try self.genBodyDebugScope(null, then_body, extra.data.branch_hints.then_cov);
                                  ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5415:58: 0x2b12383 in genBody (zig)
                .cond_br         => return self.airCondBr(inst),
                                                         ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5546:25: 0x2f8149d in genBodyDebugScope (zig)
        try self.genBody(body, coverage_point);
                        ^
/home/agni/zig/compiler/src/codegen/llvm.zig:6276:35: 0x2fcd753 in lowerBlock (zig)
        try self.genBodyDebugScope(maybe_inline_func, body, .none);
                                  ^
/home/agni/zig/compiler/src/codegen/llvm.zig:6245:31: 0x2fce3d8 in airBlock (zig)
        return self.lowerBlock(inst, null, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
                              ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5427:50: 0x2b125bd in genBody (zig)
                    const res = try self.airBlock(inst);
                                                 ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5546:25: 0x2f8149d in genBodyDebugScope (zig)
        try self.genBody(body, coverage_point);
                        ^
/home/agni/zig/compiler/src/codegen/llvm.zig:6941:35: 0x2fcab88 in airLoop (zig)
        try self.genBodyDebugScope(null, body, .none);
                                  ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5418:56: 0x2b12441 in genBody (zig)
                .loop            => return self.airLoop(inst),
                                                       ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5546:25: 0x2f8149d in genBodyDebugScope (zig)
        try self.genBody(body, coverage_point);
                        ^
/home/agni/zig/compiler/src/codegen/llvm.zig:6276:35: 0x2fcd753 in lowerBlock (zig)
        try self.genBodyDebugScope(maybe_inline_func, body, .none);
                                  ^
/home/agni/zig/compiler/src/codegen/llvm.zig:6245:31: 0x2fce3d8 in airBlock (zig)
        return self.lowerBlock(inst, null, @ptrCast(self.air.extra[extra.end..][0..extra.data.body_len]));
                              ^
/home/agni/zig/compiler/src/codegen/llvm.zig:5427:50: 0x2b125bd in genBody (zig)
                    const res = try self.airBlock(inst);
                                                 ^
/home/agni/zig/compiler/src/codegen/llvm.zig:1863:19: 0x2b0bed8 in updateFunc (zig)
        fg.genBody(air.getMainBody(), .poi) catch |err| switch (err) {
                  ^
/home/agni/zig/compiler/src/link/Elf.zig:2332:70: 0x2f46a65 in updateFunc (zig)
    if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(pt, func_index, air, liveness);
                                                                     ^
/home/agni/zig/compiler/src/link.zig:725:82: 0x2b18685 in updateFunc (zig)
                return @as(*tag.Type(), @fieldParentPtr("base", base)).updateFunc(pt, func_index, air, liveness);
                                                                                 ^
/home/agni/zig/compiler/src/Zcu/PerThread.zig:918:22: 0x26f2bac in linkerUpdateFunc (zig)
        lf.updateFunc(pt, func_index, air, liveness) catch |err| switch (err) {
                     ^
/home/agni/zig/compiler/src/link.zig:1548:32: 0x22cb0e4 in doTask (zig)
            pt.linkerUpdateFunc(func.func, func.air) catch |err| switch (err) {
                               ^
/home/agni/zig/compiler/src/Compilation.zig:3870:20: 0x1eff679 in dispatchCodegenTask (zig)
        link.doTask(comp, tid, link_task);
                   ^
/home/agni/zig/compiler/src/Compilation.zig:3647:37: 0x1c8b52e in processOneJob (zig)
            comp.dispatchCodegenTask(tid, .{ .codegen_func = func });
                                    ^
/home/agni/zig/compiler/src/Compilation.zig:3604:30: 0x1a8f919 in performAllTheWorkInner (zig)
            try processOneJob(@intFromEnum(Zcu.PerThread.Id.main), comp, job, main_progress_node);
                             ^
/home/agni/zig/compiler/src/Compilation.zig:3464:36: 0x191dfd0 in performAllTheWork (zig)
    try comp.performAllTheWorkInner(main_progress_node);
                                   ^
/home/agni/zig/compiler/src/Compilation.zig:2233:31: 0x19195d1 in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/agni/zig/compiler/src/main.zig:4412:20: 0x19536ed in updateModule (zig)
    try comp.update(prog_node);
                   ^
/home/agni/zig/compiler/src/main.zig:3603:21: 0x19bb7e2 in buildOutputType (zig)
        updateModule(comp, color, root_prog_node) catch |err| switch (err) {
                    ^
/home/agni/zig/compiler/src/main.zig:271:31: 0x183ee7e in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .run);
                              ^
/home/agni/zig/compiler/src/main.zig:200:20: 0x183bbb5 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/agni/zig/compiler/lib/std/start.zig:617:37: 0x183b6be in main (zig)
            const result = root.main() catch |err| {
                                    ^
???:?:?: 0x7f36b244d3ed in ??? (libc.so.6)
Unwind information for `libc.so.6:0x7f36b244d3ed` was not available, trace may be incomplete

[2]    23863 IOT instruction  zig-debug run result.zig

Expected Behavior

The code to compile and run.

@sin-ack sin-ack added the bug Observed behavior contradicts documented or intended behavior label Dec 8, 2024
@rohlem
Copy link
Contributor

rohlem commented Dec 8, 2024

The way I see it, the issue should be with indices[i] = i, where i as a capture of a non-inline for is a runtime value.
So the issue title should be reversed, the runtime value is assigned to the array.
I also don't think the code should compile and run,
it should trigger a compile error noting that the operand is runtime-only
and assigning to a comptime location requires a comptime-known value.

@sin-ack
Copy link
Contributor Author

sin-ack commented Dec 8, 2024

The way I see it, the issue should be with indices[i] = i, where i as a capture of a non-inline for is a runtime value.

Is it? count is a comptime variable, so I'd expect for that loop to run completely in comptime. If not, then you're correct.

@rohlem
Copy link
Contributor

rohlem commented Dec 8, 2024

The way I see it, the issue should be with indices[i] = i, where i as a capture of a non-inline for is a runtime value.

Is it? count is a comptime variable, so I'd expect for that loop to run completely in comptime.

It is, only inline for are unrolled to allow captures to become comptime values.
(Changing the loop to an inline for makes the example work once you discard the result in main.)
Normal for (originally) share the code generated for their body between every iteration.
(If they are unrolled, that is in a later optimization pass without differences in behavior.)

If you add @compileLog(i); if (true) @compileError("here"); into the loop before the assignment, the @compileLog-print shows @as(usize, [runtime value]).

@mlugg mlugg changed the title Compiler crash when assigning comptime var array to runtime value Compiler crash when assigning to comptime var array element at runtime Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior
Projects
None yet
Development

No branches or pull requests

2 participants