Does @TypeOf work in runtime?

I have a feeling that all special functions like the ones that start with @ are compile time. Given the code below (taken here):

fn deinitDeep(ptr: anytype) void {
    if (@typeInfo(@TypeOf(ptr)) != .Pointer) return;

    ...
}

It feels like the resolution of the ptr type happens during the actual run, when we invoke @TypeOf on it. At the same time, however, I have confidence that Zig does not pass, say, a meta-information attached to a pointer when we pass a pointer (or any other structures) around functions.

So my question is Zig compiler smart enough to produce specialized functions that shove the type data (structs) for every necessary place? Or @TypeOf does really work in runtime?

As a follow-up question, is the source code or definitions of these @-functions available somewhere and are they written in Zig?

1 Like

So, @-functions are called compiler builtins and they’re defined in the compiler itself, which is self-hosted, ie completely written in Zig. All compiler builtins only work at compile-time.

The anytype keyword denotes any type which will be resolved at compile-time (not the type value, just the type name). So the compiler determines that you’ll be passing a specific pointer type as anytype argument, while the pointer value becomes concrete only at runtime.

So, @-functions are called compiler builtins and they’re defined in the compiler itself, which is self-hosted, ie completely written in Zig. All compiler builtins only work at compile-time.

Thanks! That’s clear as tear.

The anytype keyword denotes any type which will be resolved at compile-time (not the type value, just the type name). So the compiler determines that you’ll be passing a specific pointer type as anytype argument, while the pointer value becomes concrete only at runtime.

However, I don’t think I understood this part completely. deinitDeep does not expect a pointer but a value named ptr which could be of anytype. Suppose, the compiler somewhere in the code infers that I called deinitDeep(x) once, where x is of type *const u8. Aha!

Since you’ve said anytype will be resolved at comptime, then @TypeOf will be able to produce *const u8 expression for another builtin @typeInfo in the if statement (at comptime as well). Does it mean that the type expression itself contains all the necessary information for the @typeInfo to produce std.builtin.Type? And am I right that at least the condition in the code above could be resolved comptime?

1 Like

Yes, the whole type system with all the exhaustive type info details is embedded into the compiler, so @typeInfo builtin can fetch that once it receives a type at compile-time.

Also, the conditional expression in the above code can only be resolved at comptime because it depends on evaluating compiler builtins, which can only be resolved at comptime. As a side note, that’s also the reason why you don’t have to use the comptime keyword here, it’s redundant.

2 Likes

Small correction here - some of the builtin functions are runtime only. @ptrFromInt is a good example of this :slight_smile:

In general, type based languages must resolve type information before runtime, so most things dealing with types directly will be comptime friendly.

5 Likes