ADR-180: A Fixed Table Holds a Declared Type as a View of One

Status: Superseded by ADR-311 — its D1-D3 are D13-D15 there Date: September 21, 2026 Target Version: Nikaia 0.0.128 Answers: open-decisions.md’s may a Fixed table hold a struct? Related: ADR-176 (the fixed map, and get’s shape), ADR-079 D1 and D3 (what crosses, and the table it crosses as), ADR-179 (&[T], the view form of a run, whose & this reuses), ADR-283 D3 (a copy is never something a compiler inserts on its own), ADR-282 D7 (the same sentence about the language below)


1. Context

comptime PAIRS: Fixed[&str, Row] = [("x", Row { a: 1 }), …] was NK1127 — this compiler cannot evaluate it. Every part of it crossed on its own: a Row is a const (ADR-079 D1), a table of &str keys is a const (ADR-176), and the combination was not. The message was also the wrong claim: the value evaluated fine, and what it could not do was cross.

The reason is get’s shape, and it is 0.0.118’s own correction. Fixed<V>::get hands back Option<V> where V: Copy, because Option<&V> put a &&str in the generated file for a table of text and ?? over one is ambiguous between two Or impls — rustc about a file nobody wrote, which Part III C.1 does not allow. A Nikaia struct derives Clone and Debug and not Copy, so a table of rows would have been that same class of error one type over. The checker refused it before it got there, which was right and said the wrong thing.

2. Decisions

D1 — Where the value is a type this program declares, the table holds &'static V.

Fixed<&'static Row>, whose vals are &[&Row { … }, …] — the & promoted to 'static by the const itself, exactly as ADR-179 D2’s &[T] is. A reference is Copy where the struct is not, so nothing about Fixed::get changes: it still hands back a value, the ledger still promises -> $V?, and ROUTES.get(k) ?? 0 still means what it reads.

What the program gets is a view of the row, which is the only thing a table living in the binary could ever have handed it — the row is 'static and there is nothing to copy it out of.

An enum is the same case, because declared_below answers for both: a table of Shade is a Fixed<&'static Shade>.

D2 — Copy is not derived on a Nikaia struct, and that is the option this does not take.

Deriving Copy wherever every field allows it was the other way to make the combination work, and it is rejected twice over.

D3 — A part of a row the language below cannot write is still NK1167, and it names the field.

A row’s fields are asked the same question a comptime struct’s are, because the table opened a second door to the same place: Fixed[&str, Bad] whose Bad holds a Vec[i64] lowered and rustc answered expected Vec<i64>, found [{integer}; 2] about the generated file. The walk that asks it now reaches a pair, which is what a table’s rows are (ADR-176 D1).

3. Consequences

4. What this does not decide

5. What is built

All of it, at 0.0.128, in a_table_that_crosses: rust_constant_type first and declared_below behind it, the & in front of each row, and the rows spelled by written_below so ADR-179 D2’s rule reaches inside them. D3 is one arm in unwritable_in.

The test runs a program, because what a table holds is a question the language below answers: crates/nikaia/tests/fixed_map.rs looks a row up, reads a field off it through ?., reads a &[&str] inside one, and misses a key.

This site is open source. Improve this page.