Add variable name to error message#1195
Conversation
tautschnig
left a comment
There was a problem hiding this comment.
-
Underlying unifier error is dropped (
fun _ => …). Forinit x : Map int bool := …where the right-hand side has typeMap string bool, the originalTC.unifyTypes(Core's, line 96 ofLanguages/Core/CmdType.lean) reports the constructor-level mismatch viaConstraints.unify's formatted output. Substituting a generic expected/inferred message hides the why. Consider preserving the original message:let τ ← (TC.unifyTypes τ [(xty, ety)]).mapError fun e => md.toDiagnosticF f!"Variable {x} expected type {xty} but initialization expression has inferred type {ety}: {TC.typeErrorFmt e}"
TC.typeErrorFmtis already in the typeclass for exactly this reason. -
No regression test exercises the new branch. I traced the closest existing test (
StrataTest/Languages/Core/Tests/StatementTypeTests.lean:81, Impossible to unify bool with int) and it short-circuits insideinferTypebefore reaching the outerunifyTypes [(xty, ety)]you patched, so the new message is currently uncovered by CI. A 3-line#guard_msgsforinit x : bool := #2(or any concrete-type mismatch where the RHS is well-typed on its own) would lock the wording in. -
.setarm has the same pattern (line 63) but is not updated. If the rationale for the new wording is that the variable name + types make the error actionable, the same applies tox := exprmismatches. Worth doing in this PR for consistency, ideally via a small helper:private def unifyOrAnnotate (md : Md) (x : P.Ident) (xty ety : P.Ty) (τ : T) : Except DiagnosticModel T := (TC.unifyTypes τ [(xty, ety)]).mapError fun e => md.toDiagnosticF f!"Variable {x} expected type {xty} but expression has type {ety}: {TC.typeErrorFmt e}"
then call from both
.initand.set(and reuse anywhere else that surfaces type mismatches against a named binding).
Minor style nit: existing error messages in this file write Variable {x} (no quotes) — see lines 36 and 54. New message uses Variable '{x}'. Pick one. Suggest dropping the quotes for consistency.
Both arms now capture the original DiagnosticModel from TC.unifyTypes and append it via TC.typeErrorFmt, so the constructor-level mismatch reason is visible instead of being silently dropped. Also fixes inconsistent quoting around the variable name (dropped quotes to match surrounding messages) and extends the same annotation to the .set arm for consistency. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tests init x : bool := strata-org#2 and set x := strata-org#2 (where x : bool) to exercise the new error paths and lock in the wording, including the appended unifier cause. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add the variable name to the error message when unification fails on initialization.