ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
34.93k stars 2.55k forks source link

ability to do conditional compilation on zig version including when builtin functions change #21957

Open andrewrk opened 4 days ago

andrewrk commented 4 days ago

Currently, if a builtin function is added to the language, it is not possible to conditionally use it depending on the Zig version number:

const builtin = @import("builtin");
const introduced_new_thing = std.SemanticVersion.parse("0.12.0-dev.1377+3fc6fc681") catch unreachable;
const have_new_thing = builtin.zig_version.order(introduced_new_thing).compare(.gte));

fn example() void {
    if (have_new_thing) {
        @theNewBuiltin();
    }
}

Without this proposal, this code would cause older versions of the compiler to produce a compile error if a call to @theNewBuiltin was found anywhere in the file.

Not all such language changes can be accounted for by checking the version number, however, many of them can, and I think adding builtins should be one of them.

However, the downside here is that bad builtin calls in dead code would no longer be reportable.

mlugg commented 4 days ago

I believe that post-1.0, it will be more beneficial to have eager reporting of incorrect builtin calls than it will to allow for forward compatibility with future builtins. At that point, while builtins can be added (a key goal of builtin function syntax is it allows us to make non-breaking extensions to the language!), I do not anticipate it happening often, and I think there will be even fewer cases where prior versions of Zig have a good solution for what the builtin intends to achieve. That's the only situation this feature would really help, because if prior versions of Zig don't have a good solution, the project likely cannot support those older versions anyway. As such, I don't think this proposal makes sense post-1.0.

However, I could see its potential benefit prior to 1.0, as Zig continues evolving. I still think I personally lean towards not allowing this; getting immediate diagnostics from ast-check whenever I e.g. misspell a builtin does, I believe, notably improve my development experience.

rohlem commented 4 days ago

The status-quo workaround for this would be to encapsulate the builtin calls in a separate module that is provided based on Zig version. (Untaken branches, i.e. if (false) _ = @import(".zig"); don't seem to prevent parsing and analysis of the file.) Probably the largest two drawbacks of this are inability to pass-through the result type (i.e. @Result() - https://github.com/ziglang/zig/issues/16313), and builtins used to affect the current scope/function (not sure whether placing them in an inline fn is always equivalent).