loop, const, macro and quote Are Names, and Their Messages Move to the Undeclared-Name HelpStatus: Superseded by ADR-298 — its D1-D3 are D6-D8 there
Date: September 16, 2026
Target Version: Nikaia 0.0.8
Related: ADR-051 (the reserved list and its rule),
ADR-071 (break, continue reserved — and loop no longer),
ADR-077 D2 (const, no longer reserved), ADR-088
D7 (macro, quote no longer reserved; with stays), ADR-116
(from, the same move for a word std needed), ADR-076 (what
the language below reserves is escaped, so it does not decide this list),
Part I 2.1, Part III C.3 (NK1117)
Four words on the reserved list were syntax nowhere: loop, const, macro
and quote. Each was kept for one reason, stated the same way each time —
a reader arriving from another language will type it, and a reserved word
can be given a message where a name cannot.
The second half of that sentence stopped being true when the checker began
refusing a name that nothing declares with a help text naming the construct
it resembles: assert c is a name and gets its
sentence. A word does not have to be forbidden to be explained.
What reserving costs is measurable in other languages’ histories and in this
one’s: the words a language later needs are almost never the ones it
reserved on stock (Java’s goto and const, thirty years unused; sixteen
of JavaScript’s stock words released again in 2009), and the words it did
reserve are names nobody may write — loop for the loop variable, quote
in a CSV grammar or a price feed. with is kept, for the opposite reason:
it has a use, and its record is next.
loop, const, macro and quote leave the reserved list.Part I 2.1’s list and the parser’s table lose the four. for loop in loops,
let quote = '"', fn const(…), a field called macro are names like any
other. The language below reserves loop, const and macro and is
answered as it is for type: the emitter escapes them (ADR-076).
A statement that is one of these names and nothing declares it is NK1117,
as any undeclared name is, and the help carries the sentence its record had:
| written | help |
|---|---|
loop { … } |
write while true { … } (Part I 3.3) |
const X = … |
write comptime X = … (Part II 10.2) |
macro …, quote … |
Nikaia has no macros; generating code from a type’s shape is comptime and a bound (Part II 10.3) |
Where the word is declared — a local, a parameter, a field — there is nothing to say, and nothing is said.
with stays, because it is about to mean something.A copy of a value with named fields changed — p with x: 1 — is the
construct the language lacks and the word fits. That is a record of its own;
until it is written, with is reserved for a construct, which is the one
ground ADR-051 has always accepted.
as break catch comptime continue dsl else
enum false fn for grammar if impl in let match mut null overlap pub return
self spawn struct sync throw throws trait true use while with.assert’s already is.with’s construct — the next record.All of it. RESERVED_WORDS is 36 words where it was 40, the four arms are
off RESERVED_C and their KW_* rules are gone with them, and NK1117 carries
the three sentences: write while true, write comptime, Nikaia has no
macros. Where the word is declared the caller never reaches the refusal,
which is D2’s nothing is said.
Each sentence ends by saying the word is an ordinary name otherwise, which
the record did not ask for and which is the half a reader who did mean a name
needs: without it, there is no unconditional loop keyword sends somebody who
wrote let loop = 3 looking for a keyword they never wanted.
D1’s answered as it is for type cost two entries in the emitter’s list.
const and loop were not in RESERVED_BELOW because a Nikaia name could not
be one of them; now it can, so they are escaped as type is — let mut loop = 1
lowers to let mut r#loop = 1, compiles and runs. macro was already there and
moves back into the sweep reserved_below.rs keeps, because the escape can
fire for it again; quote is a keyword in neither language and needs nothing,
which makes it that test’s control rather than a fourth case.
Part I 2.1’s page needed no change: it was already written for this state,
and the one word still ahead of the compiler there is from
(ADR-116).
Seven tests in crates/nikaia/tests/four_words_freed.rs, and one of them
runs: a program that binds loop and const, compiled by the same rustc
that built the test, printing 3.