iter pd.1: core API split — load_modules_with + build_workspace + implicit_imports threading
Carved load_workspace_with's inline DFS+inject+validate block into two new public fns: load_modules_with (DFS only) and build_workspace (validation + registry, takes implicit_imports: &[&str]). Threaded the new parameter through validate_canonical_type_names + check_class_ref + check_type_con_name; the four hardcoded literal-"prelude" fallback blocks in the diagnostic helpers became iter-loops over implicit_imports. load_workspace_with survives as a 3-line shim composing the new fns + the still-in-place prelude inject, so surface (ailang-surface) and all downstream crates compile + test unchanged. Retired pub fn load_workspace (zero production callers; 9 in-mod test callers migrated to load_workspace_with(&entry, load_one); load_one + the load_module import gated under cfg(test) since they're now test-only). Production literal-"prelude" count in workspace.rs dropped 8 -> 4 (all 4 in the shim's inject path; none in the diagnostic helpers, which was the spec's pd.1 target). pd.2 will move the prelude embed + the inject step into ailang-surface and retire the shim; pd.3 will delete examples/prelude.ail.json. cargo test --workspace green; bench/check.py + compile_check.py + cross_lang.py all exit 0.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
# iter pd.1 — core API split (load_modules_with + build_workspace) — surface unchanged via shim
|
||||
|
||||
**Date:** 2026-05-14
|
||||
**Started from:** 61167a4ef0ade5dd65dadfbdde1a44b65c6693ca
|
||||
**Status:** DONE
|
||||
**Tasks completed:** 6 of 6
|
||||
|
||||
## Summary
|
||||
|
||||
pd.1 carved out two new public fns in `crates/ailang-core/src/workspace.rs`
|
||||
(`load_modules_with` for DFS-only loading, `build_workspace` for validation +
|
||||
registry construction with a caller-supplied `implicit_imports: &[&str]`),
|
||||
threaded the new parameter through `validate_canonical_type_names` /
|
||||
`check_class_ref` / `check_type_con_name`, and replaced the four
|
||||
hardcoded literal-`"prelude"` fallback blocks in the diagnostic helpers
|
||||
with a parameterised iter-loop over `implicit_imports`. The surviving
|
||||
`load_workspace_with` collapses from a ~70-line inline DFS+inject+validate
|
||||
block to a 3-line composition (`load_modules_with` → caller-side prelude
|
||||
inject → `build_workspace`). The legacy JSON-only wrapper `pub fn
|
||||
load_workspace` retired with zero production callers (only doc-comment
|
||||
references and 9 in-mod test callers; the latter migrated to
|
||||
`load_workspace_with(&entry, load_one)`). Surface (`ailang-surface`) and
|
||||
all downstream crates compile + test unchanged because the shim
|
||||
preserves today's `load_workspace_with` semantics; the regression-pin
|
||||
test asserts the prelude module hash matches `load_prelude()` post-refit.
|
||||
Production-code literal-`"prelude"` count in workspace.rs dropped from 8
|
||||
to exactly the 4 expected sites (all in the shim, none in the
|
||||
diagnostic helpers). pd.2 will move the prelude-embed + the inject step
|
||||
into `ailang-surface` and retire the shim; pd.3 will delete
|
||||
`examples/prelude.ail.json`.
|
||||
|
||||
## Per-task notes
|
||||
|
||||
- iter pd.1.1: added `pub fn load_modules_with` above `load_workspace_with`
|
||||
(extracted DFS pre-amble verbatim from the old inline body); RED test
|
||||
`load_modules_with_returns_modules_without_prelude` proves the new fn
|
||||
returns modules without auto-injecting prelude. First-shot GREEN.
|
||||
- iter pd.1.2: added `pub fn build_workspace` next to `load_modules_with`
|
||||
(validation + registry construction; takes pre-assembled modules-map
|
||||
and `implicit_imports: &[&str]`). RED test
|
||||
`build_workspace_accepts_assembled_modules_and_runs_validation` ends
|
||||
the task RED-on-purpose per the plan (the inner call to
|
||||
`validate_canonical_type_names` doesn't have the parameter yet);
|
||||
Task 3 lands the green.
|
||||
- iter pd.1.3: added `implicit_imports: &[&str]` parameter to
|
||||
`validate_canonical_type_names`, `check_class_ref`,
|
||||
`check_type_con_name`; threaded it through 6 internal call sites in
|
||||
`validate_canonical_type_names` (2 in the type-walk + 4 in the
|
||||
class-ref match-arms); rewrote the two literal-`"prelude"` fallback
|
||||
blocks in the diagnostic helpers as iter-loops over `implicit_imports`.
|
||||
RED test `implicit_imports_arg_drives_prelude_fallback_in_diagnostics`
|
||||
exercises both branches (with-prelude includes `prelude.Eq` candidate;
|
||||
without-prelude excludes it). Migrated 18 in-mod test callers + 1
|
||||
production callsite (the still-inline shim body) to
|
||||
`&["prelude"]`. Task 2's test now passes. New helpers
|
||||
`module_with_bare_classref` and `module_with_class_def` use the
|
||||
existing `serde_json::from_value(json!(...))` pattern (the rest of
|
||||
mod tests' convention) rather than the plan's struct-literal style
|
||||
(which would have failed against actual `ClassDef.superclass:
|
||||
Option<...>` field shape).
|
||||
- iter pd.1.4: replaced `load_workspace_with`'s ~70-line body with the
|
||||
3-line shim composition; doc-comment rewritten to describe the shim
|
||||
role + retain the ext-cli.1 cycle-avoidance rationale on the
|
||||
loader-injection point. Pin test
|
||||
`load_workspace_with_shim_preserves_today_semantics` asserts
|
||||
prelude-module hash equality with `load_prelude()` post-refit.
|
||||
- iter pd.1.5: deleted `pub fn load_workspace`; removed it from
|
||||
`lib.rs` re-export; rewrote the workspace.rs module rustdoc example
|
||||
+ 3 lib.rs `//!` references to point at `load_workspace_with`;
|
||||
hoisted the orphaned "Algorithm: DFS over imports" doc-comment block
|
||||
onto `load_modules_with` (where it now belongs). Migrated 9 in-mod
|
||||
test callers from `load_workspace(&entry)` to
|
||||
`load_workspace_with(&entry, load_one)`. Required `#[cfg(test)]`
|
||||
gating of `fn load_one` and the `load_module` import (now consumed
|
||||
only by the test mod) to silence dead-code warnings.
|
||||
- iter pd.1.6: verification — `cargo test --workspace` all green
|
||||
(every crate's tests pass); `bench/check.py` + `bench/compile_check.py`
|
||||
+ `bench/cross_lang.py` all exit 0; production literal-`"prelude"`
|
||||
count in workspace.rs is exactly 4 (the four expected shim sites at
|
||||
lines 553/555/558/560 — all in `load_workspace_with` body — none in
|
||||
the diagnostic helpers).
|
||||
|
||||
## Concerns
|
||||
|
||||
- pd.1.2 ends RED-on-purpose per the plan. This is intentional and
|
||||
documented in the plan, but if a future iter ever bisects through
|
||||
this plan the workspace WILL NOT compile at the Task 2 boundary —
|
||||
Task 3 must land in the same Boss commit. The Boss-side commit
|
||||
shape for pd.1 is therefore "one cohesive iter commit" not "per-task
|
||||
commits".
|
||||
- pd.1.5 needed an unanticipated `#[cfg(test)]` gating step on the
|
||||
`load_one` fn + the `load_module` import. The plan didn't anticipate
|
||||
this because it framed the `load_workspace` retirement as "doc + lib
|
||||
cleanup only", but `load_one` was the only consumer of those imports
|
||||
in production. Recording so a future planner adds an "if removing a
|
||||
caller, check whether its callees become test-only" check.
|
||||
|
||||
## Known debt
|
||||
|
||||
- pd.2 will move prelude-embed (`PRELUDE_JSON` const + `load_prelude` fn)
|
||||
into `ailang-surface` and rewire surface's `load_workspace` to call
|
||||
`load_modules_with` + `build_workspace` directly, retiring the shim.
|
||||
Out of scope for pd.1 by spec.
|
||||
- pd.3 will delete `examples/prelude.ail.json`. Out of scope for pd.1.
|
||||
- The latency.implicit_at_rc improvement cluster appearing in
|
||||
`bench/check.py` (4 metrics regressed, 2 improved) reappears for
|
||||
the 4th audit in a row; cause not localised. pd.1 is a workspace.rs
|
||||
refactor with zero codegen / runtime touch, so cannot be the source.
|
||||
Baseline left pristine (consistent with audit-eob and earlier
|
||||
decisions).
|
||||
|
||||
## Files touched
|
||||
|
||||
- `crates/ailang-core/src/workspace.rs` (extraction + threading +
|
||||
shim refit + dead-fn delete + test-mod migration)
|
||||
- `crates/ailang-core/src/lib.rs` (re-export drop + 3 rustdoc updates)
|
||||
|
||||
## Stats
|
||||
|
||||
`bench/orchestrator-stats/2026-05-14-iter-pd.1.json`
|
||||
Reference in New Issue
Block a user