journal: audit — lib.rs gap sites defensive, env.imports gap was the fifth

This commit is contained in:
2026-05-10 01:24:18 +02:00
parent a9c685ded8
commit 9db47d2f4e
+80
View File
@@ -11970,3 +11970,83 @@ all three bench gates 0 regressed (`bench/check.py`,
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.
## 2026-05-10 — Audit: mono-pass env-seeding gaps (lib.rs sites + env.imports)
Targeted audit of the four `lib.rs` env-table reads that 22-tidy
flagged as gap-related, prompted by the env.globals fix (entry
above). Found a fifth gap that 22-tidy had not flagged.
**The four flagged sites** all read from `env.types` or
`env.ctor_index`:
- `lib.rs:1266``check_type_well_formed`, bare `Type::Con` lookup
- `lib.rs:1853-1856``Term::Ctor` bare-name path
- `lib.rs:1978``Term::Match` exhaustiveness, bare scrutinee type
- `lib.rs:2314-2316` — pattern-ctor resolution, local hit + type lookup
`env.types` and `env.ctor_index` are seeded workspace-flat by
`build_workspace_env` since commit 5c5180f (milestone 22c).
**All four flagged sites are therefore defensive, already
covered.** They were load-bearing *for* the 22c fix; after the
fix, they are protected.
**The unflagged fifth gap: `env.imports`.** Walking the env
struct (`lib.rs:2447-2509`) field by field against
`build_workspace_env` (`mono.rs:367`) revealed that
`env.imports` is read at four sites in `lib.rs`
`1254` / `1697` / `1836` / `2320` — but `build_workspace_env`
never seeds it. The typecheck path at lib.rs:1147-1152 builds
`env.imports` per-module from `m.imports`; the mono pass had
no analogue. RED-first repro:
- Two-module workspace: `test_mono_imports_classmod`
(class + instance) and `test_mono_imports_main` (imports
classmod, has a top-level fn body referencing
`test_mono_imports_classmod.foo` qualified).
- `ail check` passes, `ail build` fails with
`monomorphise_workspace: unknown module prefix
test_mono_imports_classmod in qualified reference`.
**Commits:**
- `2bf827f``test: red for mono-pass unknown module prefix on qualified cross-module reference in class workspace`
- Fixture: `examples/test_mono_imports_classmod.ail.json` +
`examples/test_mono_imports_main.ail.json`
- RED test: `crates/ail/tests/mono_xmod_qualified_ref.rs`
- `a9c685d``fix: mono pass seeds env.imports for qualified cross-module refs in class workspace`
- New `Env::module_imports: BTreeMap<String, BTreeMap<String, String>>` field
- `build_workspace_env` populates it from `Workspace::modules`
- `collect_mono_targets` and `collect_residuals_ordered` seed
`env.imports` per-module from it after setting `current_module`
- Mirrors the per-module pattern of `env.globals` (commit 13b36cc),
not the workspace-flat pattern of `env.types` (5c5180f) — import
aliases collide across modules.
**Verification:** RED tests for both today's bugs (`mono_recursive_fn`,
`mono_xmod_qualified_ref`) green; full workspace tests green; bench
gates 0 regressed.
**Architectural observation (not actioned this iter).** Three
consecutive commits (5c5180f, 13b36cc, a9c685d) have patched the
drift between `build_workspace_env` (mono.rs:367) and
`check_in_workspace` (lib.rs near 1095) at three different env
fields. The pattern is: every time `synth` learns to read a new
env table, both construction paths must be updated, but only one
gets it. The third occurrence is the signal — this is no longer
"audit one more place"; this is structural. Two paths to construct
the same env shape diverge under feature pressure.
**Queued for the next iteration:** unify the two env-construction
paths, OR introduce a shared helper that both call. The shape that
fits the existing code is a `build_check_env(ws: &Workspace,
current_module: Option<&str>) -> Env` in `lib.rs` (or
`workspace.rs`), with `check_in_workspace` and the mono pass both
calling into it. That removes the drift entirely, and a future
"synth needs to read env.X" change touches one site.
This is now the strongest item in the JOURNAL queue ahead of
post-22 Prelude / operator-routing / primitive-name-set
consolidation. It is not gating any user-facing feature, but it is
where the next "mysterious mono failure" will come from if not
addressed.