How does "comptime continue" work?

I’ve been writing some code using inlined loops to introspect type fields.

Removing all the actual logic, I end up with a pattern like this:

inline for (@typeInfo(T).@"struct".fields) |field| {
    const key = comptime getKey(field);
    if(runtime_map.get(key)) |value| {
        // do something with value
    } 
}

Preferring to use orelse to short circuit my loops, I got annoyed that this doesn’t work:

inline for (@typeInfo(T).@"struct".fields) |field| {
    const key = comptime getKey(field);
    const value = runtime_map.get(key) orelse continue;
}
> zig test example.zig
error: comptime control flow inside runtime block

Obviously, neither does this:

inline for (@typeInfo(T).@"struct".fields) |field| {
    const key = comptime getKey(field);
    const value = comptime runtime_map.get(key) orelse continue;
}
> zig test example.zig
error: unable to resolve comptime value

Somewhat surprisingly to me, this works:

inline for (@typeInfo(T).@"struct".fields) |field| {
    const key = comptime getKey(field); 
    const value = runtime_map.get(key) orelse comptime continue;
}

I couldn’t find a single instance of it in the language reference, the standard library, or in the Zig codebase, so here I am left wondering about this weird little expression that apparently never occurs in the wild.

Why isn’t continue comptime-scoped by default in an inline loop?

What changes about evaluating it when I tack comptime in there?

6 Likes

This has come up a few times. I think a lot of people, myself included, agree that this should work by default. There’s an open issue tracking it at 9524 and previous discussion with @mlugg generally agreeing with the idea here.

7 Likes

Thank you for the links! It’s nice seeing this has come up before and I’m just bad at searching. :sweat_smile:

To be clear, I’m not particularly surprised about continue not working. “Inline unrolls the loop so there’s no loop to continue” was just about my intuition for why continue didn’t work in the first example.

Why does it then start compiling when you comptime evaluate the continue?

1 Like