Need to be const
because the order of evaluation in the root scope is undefined and because the variables of type type
only can live in the compiler (has no memory representation, the compiler is unable to produce a binary representation of it). But you can use var
inside other scopes:
comptime {
var T = struct { value: u64 };
const x: T = .{ .value = 3 };
T = struct { ok: bool };
const y: T = .{ .ok = true };
@compileLog(x.value); // <- 3
@compileLog(y.ok); // <- true
}
Run this code
In the rest of the answer, I explain in detail.
Const
const Arith = struct {...};
Creates a constant variable of a inferred type. In this case, the variable Arith
has type type
:
const Arith = struct {...};
comptime {
@compileLog(@TypeOf(Arith)); // <- type
}
Run this code
This is the same as declare the variable as:
const Arith: type = struct {...};
Var
You also can create a variable with var
Examples:
comptime {
var Arith = struct {...};
}
comptime {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith = struct {...};
}
fn main() !void {
var Arith: type = struct {...};
}
fn main() !void {
comptime var Arith: type = struct {...};
}
Because is a variable you can modify it:
comptime {
var T = u64;
T = bool;
@compileLog(T); // <-- bool
}
Run this code
Comptime Types
There is types that can only live in the compiler, like: type
or structs that have a field of type anytype
or other comptime type.
In the case of type
, this make the compiler interpret var x: type
as comptime var x: type
.
Then, consider the following code:
var T = struct { value: u64 }; // <- Compiler error
comptime {
const x: T = .{ .value = 3 };
}
error: variable of type 'type' must be constant
because the order of evaluation in the root scope is undefined, the compiler forces to create a global variable inside the binary, but the type type
has no memory representation. So, the compiler raises an error.