From 0d3f44bee13cf683744b72710193a11f059c232c Mon Sep 17 00:00:00 2001 From: Brummel Date: Tue, 12 May 2026 22:31:57 +0200 Subject: [PATCH] iter ctt.3: KindMismatch retire --- .../2026-05-12-iter-ctt.3.json | 12 +++ crates/ail/src/main.rs | 20 ----- crates/ailang-check/src/lib.rs | 5 +- crates/ailang-core/src/workspace.rs | 68 ++--------------- docs/journals/2026-05-12-iter-ctt.3.md | 74 +++++++++++++++++++ docs/journals/INDEX.md | 1 + 6 files changed, 97 insertions(+), 83 deletions(-) create mode 100644 bench/orchestrator-stats/2026-05-12-iter-ctt.3.json create mode 100644 docs/journals/2026-05-12-iter-ctt.3.md diff --git a/bench/orchestrator-stats/2026-05-12-iter-ctt.3.json b/bench/orchestrator-stats/2026-05-12-iter-ctt.3.json new file mode 100644 index 0000000..25247d5 --- /dev/null +++ b/bench/orchestrator-stats/2026-05-12-iter-ctt.3.json @@ -0,0 +1,12 @@ +{ + "iter_id": "ctt.3", + "date": "2026-05-12", + "mode": "standard", + "outcome": "DONE", + "tasks_total": 2, + "tasks_completed": 2, + "reloops_per_task": { "1": 0, "2": 0 }, + "review_loops_spec": 0, + "review_loops_quality": 0, + "blocked_reason": null +} diff --git a/crates/ail/src/main.rs b/crates/ail/src/main.rs index 2b32c7c..00edec2 100644 --- a/crates/ail/src/main.rs +++ b/crates/ail/src/main.rs @@ -1160,26 +1160,6 @@ fn workspace_error_to_diagnostic( "method": method, })), ), - W::KindMismatch { - class, - param, - method, - defining_module, - } => Some( - ailang_check::Diagnostic::error( - "kind-mismatch", - format!( - "kind mismatch in class `{class}`: parameter `{param}` is used in applied position \ - inside method `{method}` (Decision 11 axis 5: class params are kind `*` only)" - ), - ) - .with_ctx(serde_json::json!({ - "class": class, - "param": param, - "method": method, - "defining_module": defining_module, - })), - ), W::InvalidSuperclassParam { class, superclass, diff --git a/crates/ailang-check/src/lib.rs b/crates/ailang-check/src/lib.rs index 6dfbb68..b6258c7 100644 --- a/crates/ailang-check/src/lib.rs +++ b/crates/ailang-check/src/lib.rs @@ -1425,9 +1425,12 @@ fn check_def(def: &Def, env: &Env) -> Result<()> { Def::Const(c) => check_const(c, env), Def::Type(td) => check_type_def(td, env), // Iter 22b.1: schema-only landing for class/instance defs. - // Class-schema validation (KindMismatch, InvalidSuperclassParam, + // Class-schema validation (InvalidSuperclassParam, // ConstraintReferencesUnboundTypeVar) and instance-body // typechecking (with class-method substitution) land in 22b.2. + // ctt.3: KindMismatch retired — the malformed-class-param + // shape now fires BareCrossModuleTypeRef from the canonical- + // form validator instead. // Workspace-load coherence checks (Orphan / Duplicate / // MissingMethod) already fire from `workspace::build_registry`, // so a malformed instance never reaches this point. diff --git a/crates/ailang-core/src/workspace.rs b/crates/ailang-core/src/workspace.rs index ed86651..51b86d3 100644 --- a/crates/ailang-core/src/workspace.rs +++ b/crates/ailang-core/src/workspace.rs @@ -253,22 +253,6 @@ pub enum WorkspaceLoadError { method: String, }, - /// Iter 22b.2: class-schema validation. The class parameter - /// appears in applied position (e.g. as the head of a - /// `Type::Con { name == param, args.len() > 0 }`) inside a method - /// signature. Decision 11 axis 5 forbids HKTs — class params are - /// kind `*` only. - #[error( - "kind mismatch in class `{class}`: parameter `{param}` is used in applied position \ - inside method `{method}` (Decision 11 axis 5: class params are kind `*` only)" - )] - KindMismatch { - class: String, - param: String, - method: String, - defining_module: String, - }, - /// Iter 22b.2: class-schema validation. A class's `superclass.type` /// does not equal its own `param`. Decision 11 single-superclass /// model requires the superclass to be applied to the same param @@ -789,23 +773,17 @@ fn build_registry( } /// Iter 22b.2: class-schema validation. Runs before `build_registry`. -/// Three diagnostics fire from here: `kind-mismatch`, -/// `invalid-superclass-param`, `constraint-references-unbound-type-var`. +/// Two diagnostics fire from here: `invalid-superclass-param`, +/// `constraint-references-unbound-type-var`. The `kind-mismatch` +/// diagnostic was retired at ctt.3 — the malformed shape now +/// fires `BareCrossModuleTypeRef` from the canonical-form +/// validator before `validate_classdefs` runs. fn validate_classdefs( modules: &BTreeMap, ) -> Result<(), WorkspaceLoadError> { - for (mod_name, m) in modules { + for m in modules.values() { for def in &m.defs { if let Def::Class(c) = def { - for method in &c.methods { - walk_kind_mismatch(&method.ty, &c.param) - .map_err(|()| WorkspaceLoadError::KindMismatch { - class: c.name.clone(), - param: c.param.clone(), - method: method.name.clone(), - defining_module: mod_name.clone(), - })?; - } if let Some(sc) = &c.superclass { if sc.type_ != c.param { return Err(WorkspaceLoadError::InvalidSuperclassParam { @@ -841,31 +819,6 @@ fn validate_classdefs( Ok(()) } -/// Walks a `Type` looking for any `Type::Con { name == param, args -/// non-empty }`. The class param is kind `*`; appearing as a -/// constructor with arguments is a kind-mismatch. -fn walk_kind_mismatch(t: &Type, param: &str) -> Result<(), ()> { - match t { - Type::Con { name, args } => { - if name == param && !args.is_empty() { - return Err(()); - } - for a in args { - walk_kind_mismatch(a, param)?; - } - Ok(()) - } - Type::Fn { params, ret, .. } => { - for p in params { - walk_kind_mismatch(p, param)?; - } - walk_kind_mismatch(ret, param) - } - Type::Forall { body, .. } => walk_kind_mismatch(body, param), - Type::Var { .. } => Ok(()), - } -} - /// ct.1: the five primitive type names that are always bare under /// the canonical-form rule. Kept in sync with `Type::int`, /// `Type::bool_`, `Type::str_`, `Type::unit`, `Type::float` in @@ -1876,15 +1829,6 @@ mod tests { } } - /// ct.1: a class whose parameter `f` appears as a `Type::Con` - /// name (the malformed-but-historically-test-fixture shape used - /// to trigger `KindMismatch` pre-ct.1) is now caught earlier by - /// the canonical-type-names validator: `f` is bare, - /// non-primitive, and not a TypeDef in the owning module, so - /// `BareCrossModuleTypeRef` fires before `validate_classdefs` - /// gets a chance to run. The `KindMismatch` path stays in the - /// codebase as dead-but-defensive code; a future tidy may - /// retire it. #[test] fn class_param_in_applied_position_fires_canonical_form_rejection() { let entry = std::path::PathBuf::from( diff --git a/docs/journals/2026-05-12-iter-ctt.3.md b/docs/journals/2026-05-12-iter-ctt.3.md new file mode 100644 index 0000000..1045a37 --- /dev/null +++ b/docs/journals/2026-05-12-iter-ctt.3.md @@ -0,0 +1,74 @@ +# iter ctt.3 — `KindMismatch` retire (pure deletion across 3 files) + +**Date:** 2026-05-12 +**Started from:** 0e556f085c14993441b7d25dcdc69077b77c83b0 +**Status:** DONE +**Tasks completed:** 2 of 2 + +## Summary + +`WorkspaceLoadError::KindMismatch`, its dispatch site in +`validate_classdefs`, its `walk_kind_mismatch` helper, its Display +arm in `crates/ail/src/main.rs:workspace_error_to_diagnostic`, and +the "dead-but-defensive" doc-comment on the canonical-form-rejection +test are all retired. Two adjacent textual-consistency edits ride +along: the `validate_classdefs` doc-comment narrows from "Three +diagnostics fire from here" to "Two" with a successor sentence +naming the new path, and the `crates/ailang-check/src/lib.rs:1428` +22b.1-era archaeology comment drops the `KindMismatch` token from +its enumeration of class-schema diagnostics and gains a one-line +ctt.3 retirement marker. The existing test +`class_param_in_applied_position_fires_canonical_form_rejection` +stays green unchanged — it asserts `BareCrossModuleTypeRef` on the +malformed fixture, which is the canonical-form-validator successor +the plan named. `cargo build --workspace` clean, no orphan match +arms, no dead-code warnings. `cargo test --workspace` green +(~600 tests across 16 binary-test suites, zero failures). + +## Per-task notes + +- iter ctt.3.1: atomic deletion pass — 6 Edits across 3 files. workspace.rs ×4 (variant delete; `validate_classdefs` doc + dispatch-loop delete; `walk_kind_mismatch` helper delete; "dead-but-defensive" doc delete). main.rs ×1 (`W::KindMismatch` arm in `workspace_error_to_diagnostic`). lib.rs ×1 (22b.1 archaeology comment). Build green at Step 7. +- iter ctt.3.2: workspace-wide test gate — grep substantively clean in `crates/` (one residual `KindMismatch` token at lib.rs:1431 is the ctt.3 retirement marker introduced by Step 6 itself, not a live consumer); canonical-form-rejection test PASS; full `cargo test --workspace` PASS. + +## Concerns + +- Plan-internal contradiction surfaced during Task 2 Step 1: the + plan's Step 6 `new_string` deliberately introduces a new + `KindMismatch` token in the ctt.3 retirement marker + (`// ctt.3: KindMismatch retired — ...`), but Task 2 Step 1's + verification text says "Expected: zero hits in `crates/`". The + parent spec at `docs/specs/2026-05-12-ct-tidy.md:384` is more + permissive ("`grep KindMismatch` returns the three deletion sites + only" — accepting the diff itself as the only mention, but + silent on a successor archaeology marker). Substantive intent + (retire the diagnostic) is met: variant, helper, dispatch, and + Display arm are all gone. Treated as `compliant` with this + concern recorded; Boss may choose to either tighten the + spec/plan rule for future tidies or accept the retirement-marker + pattern (which is already common in the codebase — cf. ctt.1 + successor-rationale comments in workspace.rs). +- Mid-deletion repair on workspace.rs:773 — the dispatch-loop + deletion in Step 2 orphaned the `mod_name` binding that + destructured `for (mod_name, m) in modules`. Plan Step 7's + acceptance criterion is "no dead-code warnings" — left as + `for (mod_name, m)` the build would warn `unused variable: + mod_name`. Minimal cleanup applied: rewrote to + `for m in modules.values()`. Same body, same `m: &Module` type + via `.values()` instead of tuple-destructure. Not in the plan's + verbatim edit list but a foreseeable side-effect of the + deletion and entirely mechanical. + +## Known debt + +- None new. The "future tidy may retire" promise in the deleted + doc-comment is now this iter; no successor obligation. + +## Files touched + +- `crates/ailang-core/src/workspace.rs` (variant delete + doc adjust + dispatch-loop delete + helper delete + test-doc delete + `mod_name` binding cleanup) +- `crates/ail/src/main.rs` (Display arm delete) +- `crates/ailang-check/src/lib.rs` (archaeology comment edit) + +## Stats + +bench/orchestrator-stats/2026-05-12-iter-ctt.3.json diff --git a/docs/journals/INDEX.md b/docs/journals/INDEX.md index 340ccc0..30c5e75 100644 --- a/docs/journals/INDEX.md +++ b/docs/journals/INDEX.md @@ -39,3 +39,4 @@ - 2026-05-12 — audit-eob: milestone close (heap-str-abi) — architect drift fixed inline as `eob.tidy` (3 DESIGN.md edits: float_to_str / int_to_str caveats dropped, "Str ABI" anchor added documenting both heap-Str and static-Str realisations with their shared consumer ABI and codegen-level non-RC invariant for static-Str); bench mixed (latency.explicit_at_rc improvement cluster reappears for the 3rd consecutive audit + new marginal bump_s regressions on list_sum/hof_pipeline 12% over 10% tol), baseline pristine for 3rd consecutive audit (conservative call: latency cluster has no identified cause across 3 audits — ratify-without-attribution would obscure future signal; bump_s cluster is first-sighting, observe next audit) → 2026-05-12-audit-eob.md - 2026-05-12 — iter ctt.1: env-overlay shape ratification — new DESIGN.md top-level section `## Env construction` anchors the `env.types` (owning) / `env.ctor_index` (reverse-index) split with the semantic rationale, plus the intentional check-side / mono-side asymmetry (mono-side narrowed at ct.3.2, check-side retains both halves because in-band `DuplicateCtor` consumes the per-module `env.ctor_index` rebuild); new behavioural-pin test `crates/ailang-check/tests/duplicate_ctor_pin.rs` ratifies the consumer; two P2 roadmap todos struck `[x]` (overlay shape question, per-module overlay narrowing); 3/3 tasks first-shot, zero review re-loops, no production-code edits → 2026-05-12-iter-ctt.1.md - 2026-05-12 — iter ctt.2: `Registry.type_def_module` re-key from `BTreeMap` to `BTreeMap<(String, String), String>` keyed by `(owning_module, bare_name)`; new `caller_module: &str` parameter threads through `normalize_type_for_registry` + `Registry::normalize_type_for_lookup`; four `ailang-check` consumer sites (lib.rs:1640, mono.rs:121/624/1175) pass the correct module-context (env.current_module / defining_module / module_name) per the plan's Design Notes; new regression test plus three-module fixture (`ctt2_collision_{cls,lib,main}.ail.json`) exercises the cross-module bare-name collision shape that pre-ctt.2 silently overwrote; RED-failure observed as `OrphanInstance` rather than the plan's predicted `DuplicateInstance` because the pass-2 coherence check (workspace.rs:656-659) is also a bare-name consumer and fires earlier; both consumers fixed by the same re-key; plan's verbatim two-module fixture had two structural defects (two-way imports → Cycle, qualified `InstanceDef.class` → QualifiedClassName) that the implementer-phase repair handled by introducing the third cls-module; spec-intent (RED-first against bare-name collision) preserved; `cargo test --workspace` green (16 binary-test suites, ~600 tests, zero failures) → 2026-05-12-iter-ctt.2.md +- 2026-05-12 — iter ctt.3: `KindMismatch` retire — pure deletion across 3 files (workspace.rs: variant + dispatch + helper + "dead-but-defensive" doc; main.rs: Display arm; lib.rs: 22b.1 archaeology comment). Existing test `class_param_in_applied_position_fires_canonical_form_rejection` stays green unchanged (asserts `BareCrossModuleTypeRef` on the malformed fixture — the canonical-form-validator successor path). Two adjacent textual-consistency edits ride along (validate_classdefs doc-comment "Three → Two", lib.rs archaeology comment gains a ctt.3 retirement marker). One mid-deletion mechanical fix: dispatch-loop deletion orphaned `mod_name` binding → rewrote `for (mod_name, m) in modules` to `for m in modules.values()` (same body type, mechanical). 2/2 tasks, ~600 tests green across 16 binary-test suites → 2026-05-12-iter-ctt.3.md