· 2 min read
Comptime behind glass
Zig's comptime is useful, but a public API generated where the editor can't see it makes the feature harder to trust.

Zig's comptime has a point, and I'll get to it. But here's the part that bugs me: you type a dot after a value whose type Zig has already computed, and the editor gives you nothing. The compiler knows exactly which fields are there. You, sitting in front of the editor, get to find out by running a build.
The feature is real#
Zig implements generics with compile-time parameters. Types are values at compile time, branches the compiler can resolve get specialized away, and the same function can run during compilation or at runtime. The language reference makes this one small set of building blocks carry a surprising amount of the language.
And it earns its keep. One mechanism covers generics, reflection, validation, partial evaluation, and most of what other languages reach for macros to do, while the runtime result stays boring — which is exactly what you want from a systems language.
Then you hit this:
const S = struct { alpha: u32 };fn make(comptime T: type) T { return undefined;}const foo = make(S);foo.<cursor> // compiler: S; editor: maybe silenceThe compiler knows this is S. There's an open ZLS issue reproducing the missing completion after almost this exact generic call, and ZLS's own feature list still marks support for comptime and semantic analysis as work in progress. So the answer exists, fully computed, inside a compiler the editor never gets to ask.
Developer
I just typed foo. — what is it?
Zig compiler
That is S. It has alpha: u32.
ZLS
Unknown type. Never met her.
Developer
You are both looking at the same file.
The editor is not optional#
I spend most of a working day navigating half-finished code, and almost none of it inspecting emitted machine code. So when comptime conjures up a field or a method that hover and completion can't show me, the abstraction has hidden its public surface from the one tool I'm actually looking at, and the whole feature starts to feel less safe than it is.
Build on save can surface compiler diagnostics, but ZLS maintainers note that it does not provide generated-type completion. And the problem runs deeper than a backlog: replaying arbitrary comptime inside the editor means building a second compiler, and as far as I can tell a second partial semantic engine always ends up disagreeing with the real one at the edges.
The editor is part of the language you actually use.
Keep the cleverness behind the API#
Until Zig exposes the compiler's semantic state, use comptime where it disappears: validating inputs, specializing internals, picking layouts, generating private tables. Be suspicious of any use that invents names your caller has to discover, because when the public API only exists after execution, your callers end up reading the generator source to learn what fields they actually got.
The proper fix is already named in upstream issue 615: a persistent Zig compiler server that serves compilation information through a custom protocol, with ZLS translating it into LSP. Then the editor could ask the same compiler that instantiated the type, instead of maintaining its own guess.
So yes, comptime is worth it. For now, though, the feature can express more than the tooling can explain, which is a good reason to keep the clever parts behind an API your editor can still see. The rest can wait for the compiler server.