journal: bug fix — mono pass env.globals seeding

This commit is contained in:
2026-05-10 01:12:11 +02:00
parent 13b36ccb0f
commit ca8ffe8dc3
+58
View File
@@ -11912,3 +11912,61 @@ compile today. RED-first debug iter follows.
**Action items spawned by this iter:**
- RED-first debug iter for the `env.globals` mono bug.
## 2026-05-10 — Bug fix: mono-pass `env.globals` not seeded — recursive top-level fn in class workspace
Surfaced by the mono-vs-vdisp bench (entry above). RED-first per
`skills/debug` discipline; one RED-test commit, one GREEN-fix commit.
**Symptom.** `ail build` on a workspace containing one `Def::Class`,
one `Def::Instance`, and a self-recursive top-level `Def::Fn`
exits with `monomorphise_workspace: unknown identifier <fn-name>`.
`ail check` on the same fixture passes — proof that the typechecker
is fine and the gap is in the mono pass.
**Cause.** `crates/ailang-check/src/mono.rs::collect_mono_targets`
(line 463) and `collect_residuals_ordered` (line 819) both
re-run `crate::synth` on a fn body to recover residual class
constraints, but their `env` (built by `build_workspace_env`) only
populates `module_globals` (per-module index) — not `globals` (the
flat current-module table that `synth`'s `Term::Var` lookup at
lib.rs:1678 actually reads). The main check path handles this at
lib.rs:1135-1139, seeding `env.globals` per module before `synth`
runs; mono.rs did not. Sibling gap to commit 5c5180f's
`env.types` / `env.ctor_index` fix from milestone 22c — same
shape, different env table.
**Fix.** Two-line seed in each of the two `synth`-rerun call
sites: `if let Some(g) = env.module_globals.get(module_name).cloned() { for (n, t) in g { env.globals.insert(n, t); } }`.
Per-module scope (not workspace-wide), because top-level fn names
are only per-module-unique — `build_module_globals`
(lib.rs:1011-1019) enforces uniqueness within a module, not
workspace-wide. A flat workspace seed would silently shadow
same-named fns across modules. The semantically-correct mirror of
lib.rs:1135-1139 is per-module, not the workspace-wide pattern
5c5180f used for types/ctors (which are workspace-unique).
**Commits:**
- `3b0bcf3``test: red for mono-pass unknown identifier on recursive fn in class workspace`
- RED test: `crates/ail/tests/mono_recursive_fn.rs::mono_pass_handles_recursive_fn_in_class_workspace`
- Fixture: `examples/test_mono_recursive_fn_bug.ail.json`
- `13b36cc``fix: mono pass seeds env.globals for recursive top-level fn in class workspace`
**Verification:** RED test passes, full workspace tests green,
all three bench gates 0 regressed (`bench/check.py`,
`bench/compile_check.py`, `bench/cross_lang.py`).
**Carried debt (untouched per Iron Law):**
- Drift-risk comment in `build_workspace_env` says "If `synth`
starts reading a new `Env` field, update both paths" — accurate
but `env.globals` is now seeded in two further places (the
`collect_*` fns themselves) which the comment doesn't mention.
Cosmetic; left alone for the next consolidation pass.
- The four lib.rs gap-related sites flagged in 22-tidy
(`lib.rs:1266 / 1853-1856 / 1978 / 2314-2316`) and the
primitive-name-set consolidation remain queued. This bug
proved one of the env-seeding "gaps" from 22-tidy was
load-bearing, not defensive — a future iter that audits all
four flagged sites is worth its cost.