# Session 2026-10-19 — summary Branch **`master`** (tree clean). Eleven commits, tagged individually (`v3-generics-two-instances` … `v3-pim-io-libs`). Plan source: `handoff-2026-10-18-next.md` (P0–P5) + `handoff-2026-10-19-next.md`. ## Numbers | gate | session start | end | | --- | --- | --- | | suite (`compiler/run_tests.sh`) | 239/239 | **249/249** | | fixpoint (`bootstrap/fixpoint.sh`) | OK (3,812,771 B) | **OK (3,882,337 B)** | | corpus (`tools/v3-corpus/corpus.sh`) | 405/612 | **467/612, 0 crashes** | Reproduce: ```sh cd compiler && ./build.sh && ./run_tests.sh # 249/249 cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh tools/v3-corpus/corpus.sh # 467 OK, 0 crash ``` ## What landed ### P0 — generics double-instantiation (real bug) — `dc3b3c8` One generic instantiated twice with different-family type arguments failed on the second. Root cause was **Lowering**, not the formal binding: after `EndUnit`, `Lower` re-emitted each unit in `globScope`, so `MaterializeGlobals` copied the unit's types there; a generic instance leaked its `NodeRec` and the second instance's `POINTER TO NodeRec` resolved the first instance's record via `ForwardType`. Fix: `SymTab.EnterLowerScope`/`LeaveLowerScope` (re-emit each unit in its own scope), `Lower.ReenterImports` for nested-module FROM-imports. Regression `g_twice*` / `GTwiceProg`. ### P1 — two gm2 extensions (user chose compatibility) — `a33fc7c`, `b042be3` - `__FILE__` / `__LINE__`: scanner allows a leading `_`; both are reserved literals folded to the file-name string / line-number integer. - scalar actual → `ARRAY OF BYTE`: parse-time marker on the open formal; a scalar is wrapped in a stack descriptor `[count=SIZE(actual)][copy]` (`QbeGen.OpenScalarDesc`). Approximate by design (writes hit the copy; `BYTE` stays 32-bit) — documented in `gaps/README.md`. ### P2 — structural gm2 extensions — `81b488b` `gap10` same-size scalar `VAR` actual; `gap11` PIM `PROC` type + bare proc-value statement; `gap12` variant empty arms / `ELSE` / comma labels / untagged inner `CASE` / nested variant `CASE`; `gap18` set-typed `CASE` labels (word-wise `CmpSet`). Corpus +16. ### P3 — strict declaration order in bodies — `10e0951` Deferred bodies are now order-aware for this module's own **data** (variables/constants/types): `SymTab` declaration sequence + a window in `Lookup`; parser state moved so the parser obeys the rule. Forward **procedure** calls stay allowed (the generated parser relies on it; gm2's bootstrap link rejects `FORWARD`). Corpus −6 (intended: gm2 `decl-order` leniencies now correctly rejected). ### P4 — the "size-sensitive" miscompile — `a50fc6f` (docs) **Not size-sensitive, not a codegen bug.** `ASTDUMP` dumped the AST to stdout; built from its own sources that dump contained the driver's literal `"Parsed correctly"`, and the fixpoint gate was `grep -q Parsed` — so the gate passed while the session reported `Incorrect source`. Removing the dump unmasked real errors (Lower's forward procedure calls), already fixed in `a3ef897`. Also corrected the stale note about the record-array-field codegen bug (`38e0b54`): it is **fixed** (hybrid `ArrBodyItems`), covered by `t_arrrecfld`/`t_arrrecbig`/`t_nestarr`. ### gap14 + P5 — `f53cdad` - `__BUILTIN__` / `__ATTRIBUTE__` declaration pragmas parsed and ignored (`builtin.def/.mod` + 4 importers now compile). - `docs/INDEX.md` rewritten; 45 unreferenced historical files moved to `docs/archive/` (all 69 cross-references kept valid). - `gap13` remainder (standard built-ins as identifiers) documented and **deliberately deferred**: no corpus exemplar, and it needs a contextual-keyword rewrite of `Fact`/`ArgList` (Coco/R is LL(1)); a declaration-site-only measure would silently bind calls to the built-in. ### Robustness — `3d58325` Table-limit overflows are now loud (`230`), not silent drops: the two-phase span table (used to silently drop a body's codegen — regression `t_manyproc`), the label/`GOTO` tables, the 32-actual AST buffer, and `SymTab.MaxTypes`. Corpus unchanged (no corpus file hits a limit). ### Library — `c7d5cff`, `d243d25` - ISO 10514-1 `ChanConsts` + `StreamFile` on `IOChan`; PIM/gm2 `NumberIO`, `RealInOut`, `FpuIO` (new shim `m2writefix`). - Two real compiler bugs surfaced and fixed: **cross-unit set `CONST`s** (emitted under the global name now) and **qualified enum literals in set constants** (`Lower.EvalOrdConst`). - Harness fidelity: `corpus.sh` now resolves V3's own shipped libraries by default (`V3_LIBS`), instead of mislabelling their imports `LIB`. ## Corrections / lessons - The "size-sensitive miscompile" and the "still-open record-array-field bug" were both stale notes; both are resolved. Verify old findings before acting on them. - A weak success gate (`grep -q Parsed`) can mask real errors — the gate now greps `Parsed correctly` and fails on session errors. ## Remaining (for a next session) 1. **Corpus `LANG` bucket** — after the library work: `undeclared identifier` (gm2-only modules `M2RTS`/`Builtins`/`Processes`/… aside), `not supported yet`, `invalid call`. Triage the top kinds. 2. **Error recovery / message polish** — dropped tokens cascade. 3. **`gap13` refactor** (optional, no corpus exemplar). 4. `STATUS.md` "what remains" is the live list. Nothing was pushed; `origin/master` is the previous commit.