A not-immediately-fatal way of indicating that a feature is unavailable

In many places in the standard library, you see the use of @compileError() as a mean to indicate that a feature is unavailable for one reason or another. Sometimes it’s a function:

pub const min = @compileError("deprecated; use @min instead");

Sometimes it’s a type:

        pub const Writer = if (T != u8)
            @compileError("The Writer interface is only defined for ArrayList(u8) " ++
                "but the given type is ArrayList(" ++ @typeName(T) ++ ")")
        else
            std.io.Writer(*Self, Allocator.Error, appendWrite);

The presence of these @compileError() calls make it impossible to scan the structures in question. As soon as you touch the decl it blows up on you. A better mechanism is really needed, I think, that would allow meta-programming code to detect such instances in order to avoid them while at the same time getting the message across to programmers.

I am not getting the problem. How do you scan or touch the decl?

For example:

const std = @import("std");

pub fn main() void {
    const T = std.fs.Dir;
    const decls = @typeInfo(T).Struct.decls;
    inline for (decls) |decl| {
        _ = @field(T, decl.name);
    }
}
/home/cleong/.zvm/0.13.0/lib/std/fs/Dir.zig:2386:24: error: deprecated; renamed to writeFile
pub const writeFile2 = @compileError("deprecated; renamed to writeFile");
                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 Likes