Lyricdev
GitHub

LYR-SEM0100

a 'comptime' form that cannot be evaluated while compiling

error · spec 11-metaprogramming

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}");
}
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}");
}