Issue #1199: Build ADR-389: immutable (deep immutability, once-evaluated item level, NK1331)

Open and answer this issue on GitHub.

ready · opened 2026-11-03 · updated 2026-11-03 · 1 comment

Build ADR-389: immutable, a binding whose value nothing reachable from it ever changes (Part I 2.1, NK1331 in Part III C.3).

Probe (refused today, the word is not reserved yet):

immutable DUMP_DIR: String? = env::var("NIKAIA_DUMP_ACCEPTED")

fn main() {
    immutable limits = [1, 2, 3]
    let a = async fn { print(f"{limits.len()}") }
}

To build

  1. Lexer: immutable on the reserved list.
  2. Parser: the binding inside a function body and at item level, with an optional type and pub.
  3. Checker: the deep rule (D2): a type reaching SharedMut, Locked, a channel end or another shared changeable handle is refused with NK1331, naming the path; no ref mut self calls, no moves out.
  4. Checker: item-level initializer may not throw (D5), and a cycle among item-level immutables is refused (D4), both NK1331.
  5. Tasks: an immutable capture or argument gets no copy, no count and no NK2101 (D3).
  6. Code generation: item level as a once-evaluated, thread-safe cell (LazyLock); function level as a plain binding.
  7. Tests in tests/compiler/ for each rule and each refusal.
  8. Use it for accepted_dump_dir() in the move of check_walked (#125).

Generated by Claude Code

Comments

keywan-ghadami, 2026-11-03

Step 1 also puts immutable on the reserved-word list of Part I 2.1 (the text block under Reserved words) and adds, before the comptime paragraph there: “immutable is reserved for its construct: a binding whose value nothing ever changes, deeply, where an item stands or inside a function body (2.1).” The page held it before the parser did and from_is_a_name::the_page_and_the_table_list_the_same_words went red, so ef80da01 took it out until this build. Note: the compiler’s own .nika uses immutable as a field name (found.immutable, local.immutable); rename those in the same build.


Generated by Claude Code

Back to Open Issues