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

60 lines
2.3 KiB
Markdown

# 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.rs`
`check_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.