Files
AILang/docs/journals/2026-05-15-bugfix-mut-diag-double-code.md
T
Brummel 1ff7e811af fix: mut-local diagnostics doubled the [code] prefix in human stderr (fieldtest F2)
The four mut-local CheckError variants (MutAssignOutOfScope,
AssignTypeMismatch, UnsupportedMutVarType, MutVarCapturedByLambda)
embedded the bracketed kebab code in their thiserror Display body,
while the non-JSON CLI formatter independently prepends [code] from
CheckError::code() — doubling it. Non-mut variants never embedded
the bracket; this brings the four in line with that convention.

RED-first via the debug skill: ct1_check_cli.rs pins the observable
property (code appears exactly once in the rendered human
diagnostic). GREEN was a trivial four-string mechanical edit.

Tests 598 -> 599.
2026-05-15 10:13:50 +02:00

2.3 KiB

bugfix mut-diag-double-code — doubled [code] prefix in mut-local human diagnostics

Date: 2026-05-15 Status: DONE Trigger: fieldtest finding F2 (docs/specs/2026-05-15-fieldtest-mut-local.md). Started from: 1faee67

Symptom

Non-JSON ail check stderr rendered the kebab diagnostic code twice for the four mut-local CheckError variants, e.g.

error: [mut-var-captured-by-lambda] main: [mut-var-captured-by-lambda] mut-var `x` cannot be captured...

Cause

MutAssignOutOfScope, AssignTypeMismatch, UnsupportedMutVarType, MutVarCapturedByLambda were authored in iters mut.2 / mut.4-tidy with their #[error("[<code>] ...")] thiserror Display bodies embedding the bracketed code. The non-JSON Cmd::Check formatter in crates/ail/src/main.rs independently prepends [{d.code}] from CheckError::code(). Embedded + prepended = doubled. The non-mut CheckError variants never embedded the bracket, so only these four doubled — they were the inconsistent ones, brought in line here.

Fix

RED-first via the debug skill (ailang-debugger wrote the failing test; the GREEN side was a trivial four-string mechanical edit applied inline by the Boss per the CLAUDE.md trivial-mechanical-edit carve-out — no review-and-commit discipline shed).

  • RED test: crates/ail/tests/ct1_check_cli.rscheck_human_mode_renders_mut_diagnostic_code_exactly_once. Pins the observable property: the code appears exactly once in the rendered human diagnostic, exercising the same formatter path the CLI uses (not a brittle assertion on the raw #[error] body).
  • GREEN: dropped the leading [<code>] literal from the four #[error(...)] Display strings in crates/ailang-check/src/lib.rs.

The mut-typecheck pin tests (mut_typecheck_pin.rs) and the in-source unit assertions match on the struct variants / code(), not the Display string, so the prefix removal did not touch them.

Tests

598 → 599 green (the new RED-now-GREEN human-formatter test). Full workspace clean, zero failures.

Not in scope (stays queued)

F1/F4 (accumulator-over-iteration: the milestone motivation is unmet without a loop construct) and F3 (zero-arg (app f) rejected at parse) from the same fieldtest are NOT addressed here — they are design/roadmap items, not this bug.