from Is a Name, and a File a Build Reads Is asset("…")Status: Superseded by ADR-310 — its D1-D3 are D12, D3 and D13 there Date: September 16, 2026 Target Version: Nikaia 0.0.8 Related: ADR-298 (the reserved list, which loses a word), ADR-072 (a file a build reads is named three times — the code’s spelling changes, the rule does not), ADR-296 D27 (which had kept the word for this), ADR-026 D2 (a build-time path stays inside the project), ADR-298 (names the language below reserves are escaped, so Rust does not decide this list), Part I 2.1, Part II 10.6, Part III 13.1 and 17.1
from was reserved, and it bought one phrase: Json.value(from
"config.json"), the read of a file at build time, checked against an
allowlist and embedded in the binary. The parser used the word in one rule,
and that rule exists only to print a helpful message for the removed form
dsl X from e. Nothing live in the compiler parsed from.
What the word cost was itself. from/to is the pair every API reaches for
— renaming, copying, ranges, transfers, spans of time — and the
specification’s own fs::rename(from: Path, to: Path, …) could not be
written in the language, because a reserved word is a name only after ::
and .. A test’s countdown had already been renamed from from to start
to make room.
The reserved list was chosen when there were no programs outside this repository, on the ground that the choice was free then in a way it would never be again. The same ground makes freeing a word free today.
from is an ordinary name.It leaves the reserved list in Part I 2.1 and in the parser’s table.
fn rename(from: Path, to: Path), let from = 10, p.from are what they
look like. The parser’s message for the removed dsl X from e matches the
bare word, and loses nothing.
asset("…").comptime CONFIG: Json::Value = Json.value(asset("config.json"))
comptime ROUTES = Routes.table(asset("routes.txt"))
asset is the compiler’s, not std’s: it is recognised inside a comptime
initialiser, its argument is a string literal and may not be computed, the
path is under the project root, and the literal is what the allowlist is
checked against — every rule ADR-072 states holds unchanged,
under a call rather than a keyword. The word is the one Part III 13.1 already
uses for what these files are (asset hashing). Written anywhere but a
comptime initialiser it is refused, and the message says that a file read
while the program runs is fs::read.
std writes from: where it meant to.fs::rename(from: Path, to: Path, root: Root) and fs::copy(from:, to:,
root:) parse as Part III 17.1 has them.
Json.value(asset("config.json")) says when
(comptime), where from (asset) and what with (Json.value) in the
same three places the keyword did.from,
and a name Rust does reserve is escaped anyway (ADR-298).asset may one day mean these bytes, embedded outside
comptime. Refused today, and a later record may allow it.D1 and D3, at 0.0.122. from is out of parser::RESERVED_WORDS and out of
the grammar’s RESERVED alternation, so it is a name in every position that
declares one — a field, a parameter, a let, a member — and Part III 17.1’s
pub fn rename(from: Path, to: Path, …) parses as the page writes it. Rust does
not reserve the word either, so nothing is escaped on the way down
(ADR-298): one table, not two.
The removed form keeps its sentence, which is the whole of what the
reservation was paying for. dsl X from e still gets a grammar is entered by
a call rather than a parse error at whatever token is next — from the grammar’s
token rather than from the reserved list, and those are two different things.
D1’s loses nothing is literal.
And the page had drifted. Part I 2.1 prints the list a reader learns and
parser::RESERVED_WORDS is the one the compiler enforces. select arrived with
its construct (ADR-292) and reached the table and not the page, so
a reader counting the words there got a different answer from the compiler.
Both say the same thirty-six now, and a test compares them rather than a memory.
And D2, at 0.0.123, with ADR-072 built under it.
comptime CONFIG: &str = asset("config.txt") reaches the generated file as a
const holding the file’s text. asset is the compiler’s and not std’s, so
it is recognised in a comptime initialiser and refused with NK1177
anywhere else — and that refusal names fs::read, because a file read while
the program runs is what a reader who wrote it there almost certainly
meant. Every rule ADR-072 states holds unchanged under the call
rather than under the keyword it was written for; that record’s §4 says which.
Three words each decide one thing, and the refusal says so: comptime says
when, asset("…") says where the bytes come from, and the call around
it says what is done with them.
What is left is not this record’s. The two fs entries wait on
ADR-108’s root, which is a different record’s, and running a
grammar over what asset read waits on compiling the generated parser
rather than interpreting the grammar (#178).
#178 carries the rest.