Targeted hint on ILO-T003 ternary branch-type mismatch - #582
Merged
Conversation
Before, the verifier emitted the generic 'both branches of a ternary must return the same type' hint with no signal on which side to convert. Agents either guessed (often producing a follow-on type error) or restructured unnecessarily. The new hint reads the two branch types and: - for n vs t, surfaces both conversion directions: 'str <num-branch>' to make both text, or 'default-on-err (num <text-branch>) <fallback>' to make both number (since 'num' returns R n t, an unwrapped scalar is not enough); - for everything else (bool vs text, L n vs M t n, two named records, R T E vs n, ...), falls back to restructure advice because str/num are the only built-in scalar coercions; suggesting one outside that pair would just trip ILO-T013.
Pins the new ILO-T003 hint shape across the four cases that matter: - n vs t in either branch position must surface both 'str <num-branch>' and 'default-on-err (num <text-branch>)' so the agent can pick the direction matching intent; - matching-type ternaries still verify clean (false-positive guard); - bool vs text and list vs map fall back to the restructure hint, with explicit negative asserts that we don't suggest a str/num conversion that wouldn't apply. Adds examples/ternary-types.ilo showing the canonical correct shapes after applying each hint. The examples_engines harness runs it across every available engine on every CI run, so the docs and the verifier hint can't drift apart silently.
SPEC already documents the ILO-T038 'condition must be b' rule next to the prefix-ternary explanation; this slots the matching ILO-T003 rule in the same place so agents reading the ternary spec see both checks together. ai.txt regenerates from SPEC.md via build.rs.
danieljohnmorris
added a commit
that referenced
this pull request
May 21, 2026
Targeted hint on ILO-T003 ternary branch-type mismatch
❌ 1 Tests Failed:
View the top 1 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Before: a ternary like
?h c 1 "x"produced ILO-T003 with the generic hint "both branches of a ternary must return the same type". Agents either guessed which side to convert (often producing a follow-on ILO-T013) or restructured unnecessarily. Common gotcha across personas; addressing pending.md #5h.After: the verifier reads the two branch types and emits a targeted suggestion.
nvstsurfaces both conversion directions (str <num-branch>for the text intent,default-on-err (num <text-branch>) <fallback>for the number intent) so the agent picks whichever matches the function's return type. The hint explicitly mentionsnumreturnsR n t, which avoids the very common follow-on bug of treating the parse result as a bare number.L nvsM t n, two named records,R T Evsn, ...) falls back to restructure advice. The only builtin scalar coercions in ilo arestr(n→t) andnum(t→R n t), so suggesting a coercion outside that pair would just trip ILO-T013. Better to point at[...]/ record /O T/R T Eframings explicitly.Manifesto framing: cheaper hint, fewer retries. The agent now reads the diagnostic once and writes the fix, rather than walking through two or three failed compile cycles.
Repro
Before:
After:
What's in the diff
fix(verify): targeted hint on ILO-T003 ternary branch mismatch— newternary_mismatch_hinthelper insrc/verify.rs; the existingExpr::Ternarymismatch path calls it instead of hard-coding the generic string. Pure diagnostic, no codegen / parser / AST surface change.test: regression coverage for ternary type-mismatch hint— six new tests intests/regression_ternary_type_hint.rspinning the four shapes (n-vs-t in either branch position, bool-vs-text fallback, list-vs-map fallback, matching-branch false-positive guard). Addsexamples/ternary-types.iloshowing the canonical correct shapes; theexamples_enginesharness exercises it across every available engine on each CI run.doc: note ternary branch-type hint in SPEC ternary section— short paragraph in SPEC.md next to the existing ILO-T038 paragraph;ai.txtregenerates from SPEC.md viabuild.rs.Test plan
cargo test --release --features cranelift --test regression_ternary_type_hint— 6/6 passcargo test --release --features cranelift --lib verify— 429/429 pass (existingternary_branch_type_mismatch_errorstill green)cargo test --release --features cranelift --test examples_engines— passes, picks up the newternary-types.ilocargo fmt --checkclean,cargo clippy --all-targets -- -D warningscleancargo test --release --features cranelift— only failures observed are pre-existing onmainand unrelated (spec_reserved_short_names_match_builtin_registry,body_is_thin_bootstrap)Follow-ups
bool→text), update theternary_mismatch_hintstrategy to surface the new direction.