LYR-SEM0100
a 'comptime' form that cannot be evaluated while compiling
A 'comptime' expression, 'comptime if' or 'comptime for' asks for something the compiler cannot compute and keep as a constant: a result that is no literal (an object of a class), a read of 'this' or of a local of the enclosing function, an assignment to anything it does not bind itself, a 'comptime for' over something other than an array, a 'comptime if' with a 'let' condition or with arms of two types.
Explanation
A comptime site is evaluated once, while compiling, and its result is written into the compiled module as a literal. So the result must be a value a literal can make — a scalar, a string, or an array, struct, enum, tuple, optional or Box of such — and not an object of a class, which has an identity no literal gives. The site may read only module-level names and what it binds itself: this, the parameters and the locals of the enclosing function exist only at run time, and a module's variables belong to the run.
comptime for walks an array the site computes and binds each element to a plain name; comptime if chooses by a bool computed while compiling, and its two arms are one value of one type.
Compute a value-typed result (a struct instead of a class), move what the site reads to module level, or drop comptime and compute the value at run time.
Wrong
import std.io { println };
class Counter {
var n: int = 0,
}
fn counter(): Counter {
return Counter { };
}
fn main(): void {
let c = comptime counter();
println(f"{c.n}");
}
Right
import std.io { println };
struct Counter {
n: int,
}
fn counter(): Counter {
return Counter { n = 0 };
}
fn main(): void {
let c = comptime counter();
println(f"{c.n}");
}