ADR-117: loop, const, macro and quote Are Names, and Their Messages Move to the Undeclared-Name Help

Status: 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)

1. Context

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.

2. Decisions

D1 — 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).

D2 — What each word used to be told, the undeclared-name refusal now tells.

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.

D3 — 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.

3. Consequences

4. What this does not decide

5. What is built

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.

This site is open source. Improve this page.