comptime Binding Where an Item StandsStatus: Superseded by ADR-287 — its D1-D4 are D9-D12 there
Date: September 15, 2026
Target Version: Nikaia 0.0.8
Related: ADR-073 D2 (which decided both places and built one),
ADR-077 (the word), ADR-047 D2 (what pub means
across a package), ADR-011 D2 (why the emitter is handed the
spelling rather than working it out)
comptime MAX = 1000 // at the top of a file: a parse error
fn f() { comptime MAX = 1000 } // inside a body: parses, folds, runs
ADR-073 D2 decided both places and built one. Part I 9.2
already lists Constants among the items pub applies to, so the rule for a
constant another package may read was written and the syntax for one was not.
Item::Comptime had been in the AST since that record, with its public field,
and nothing produced or consumed it — a variant nothing reaches is a
decision that looks built from the inside.
pub on the statement.The two produce different types — a Stmt and an Item — and one rule handing
back either is a rule that says less about where it may stand. pub belongs to
this one because Part I 9.2’s rule for Constants is what it means here.
ADR-073 D2 says the difference between the two is “where the name
is visible, never what may stand to the right of the =“, so
Checker::comptime_binding is what both callers run: the fold, NK1127, the
declared-type check and the spelling the emitter is handed are one thing in one
place. Three copies would be three chances for the two places to disagree about
what a constant is.
This checker’s scope is a stack pushed per function, so an item-level name needs a frame under all of them. Both halves of “a pass, before the loop” are load-bearing:
const MAX: i32 = 1000;, keyed by the item’s own byte offset through
Checked::comptime_values. This emitter knows no types
(ADR-011 D2), so what 1000 is called below is not a question it
can answer — and Rust’s const will not take the absence. pub reaches Rust’s
own pub, which is what another package reads
(ADR-047 D2).
Two lines move in tests/errors/EXPECTED.txt, both correct: comptime now
appears in the list of what may stand where an item does, which is a parse
error’s note getting truer.
NK1127 reaches the item form through the shared function rather than through a
second copy — which matters, because a place where it did not fire would be
a place where comptime quietly means let, and that is the promise the word
exists for.
#232’s entry closes — a comptime binding at item level has
nowhere to stand.
true and false. A call is still refused by name, and #174
carries the evaluator as its own entry.pub comptime is in another package’s ledger. The pub reaches
Rust and another crate can read it; whether this compiler records one in
nikaia.contracts is ADR-020’s question and nothing here adds
a column.comptime DOUBLE = MAX * 2 folds because the
pass walks items in source order and MAX is already bound. A constant that
reads one declared below it is not refused with a sentence of its own —
it meets NK1117, which is honest and not the best message it could get.comptime_item in the grammar; Checker::item_constants and
Checker::comptime_binding, the second extracted from the statement arm so both
callers share it; the Item::Comptime arm in the emitter, with Emitter::item
given the span it needs to read the checker’s answer. Exercised by five programs
in crates/nikaia/tests/comptime_item.rs — the whole shape compiled and run,
a function above the constant on its own, NK1127 at item level, the two places
folding one initialiser to one const, and pub in both directions.