Skip to content

Discrepancy in handling of comptime vars in defer statements #24213

Open
@emmarion

Description

@emmarion

Zig Version

0.15.0-dev.832+1ca213dab

Steps to Reproduce and Observed Behavior

I have two pieces of code which I think should compile/behave identically.

The first one results in i being 2, which I find to be odd:

fn nop() error{E}!void {}

pub fn main() !void {
    comptime var i = 0;
    {
        defer {
            i += 1;
        }
        try nop();
    }
    @compileLog(i); // outputs 2
}

Result:

src/main.zig:11:5: error: found compile log statement
    @compileLog(i); // outputs 2
[...]
Compile Log Output:
@as(comptime_int, 2)

The second one results in a compile error due to "comptime variable depends on runtime condition":

fn nop() error{E}!void {}

pub fn main() !void {
    comptime var i = 0;
    {
        defer {
            i += 1;
        }
        nop() catch |e| return e;
    }
    @compileLog(i); // statement is never reached
}

As shown here:

src/main.zig:7:15: error: store to comptime variable depends on runtime condition
            i += 1;
            ~~^~~~
src/main.zig:9:15: note: runtime condition here
        nop() catch |e| return e;
        ~~~~~~^~~~~~~~~~~~~~~~~~

I'm not sure which of these is correct, however the discrepancy seems odd to me.

Expected Behavior

The two code samples should behave identically.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behaviorfrontendTokenization, parsing, AstGen, Sema, and Liveness.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions