Skip to content

Targeted hint on ILO-T003 ternary branch-type mismatch - #582

Merged
danieljohnmorris merged 3 commits into
mainfrom
fix/ternary-type-hint
May 21, 2026
Merged

Targeted hint on ILO-T003 ternary branch-type mismatch#582
danieljohnmorris merged 3 commits into
mainfrom
fix/ternary-type-hint

Conversation

@danieljohnmorris

Copy link
Copy Markdown
Collaborator

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.

  • n vs t surfaces 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 mentions num returns R n t, which avoids the very common follow-on bug of treating the parse result as a bare number.
  • Everything else (bool vs text, L n vs M t n, two named records, R T E vs n, ...) falls back to restructure advice. The only builtin scalar coercions in ilo are str (n→t) and num (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 E framings 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

ilo 'f c:b>t;?h c 1 "x"' --vm f true

Before:

ILO-T003 ternary branches have different types: n vs t
  hint: both branches of a ternary must return the same type

After:

ILO-T003 ternary branches have different types: n vs t
  hint: both directions are available: `str <num-branch>` makes both
        text (cheapest if the function returns `t`), or parse the text
        side with `default-on-err (num <text-branch>) <fallback>` to
        make both number (since `num` returns `R n t`). Pick whichever
        matches intent, or restructure to wrap each branch in a
        list/record/`O T` to keep both shapes

What's in the diff

  • fix(verify): targeted hint on ILO-T003 ternary branch mismatch — new ternary_mismatch_hint helper in src/verify.rs; the existing Expr::Ternary mismatch 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 in tests/regression_ternary_type_hint.rs pinning the four shapes (n-vs-t in either branch position, bool-vs-text fallback, list-vs-map fallback, matching-branch false-positive guard). Adds examples/ternary-types.ilo showing the canonical correct shapes; the examples_engines harness 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.txt regenerates from SPEC.md via build.rs.

Test plan

  • cargo test --release --features cranelift --test regression_ternary_type_hint — 6/6 pass
  • cargo test --release --features cranelift --lib verify — 429/429 pass (existing ternary_branch_type_mismatch_error still green)
  • cargo test --release --features cranelift --test examples_engines — passes, picks up the new ternary-types.ilo
  • cargo fmt --check clean, cargo clippy --all-targets -- -D warnings clean
  • Full cargo test --release --features cranelift — only failures observed are pre-existing on main and unrelated (spec_reserved_short_names_match_builtin_registry, body_is_thin_bootstrap)

Follow-ups

  • None required. If a future PR widens the set of builtin scalar coercions (e.g. bool→text), update the ternary_mismatch_hint strategy to surface the new direction.

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
danieljohnmorris merged commit 9444236 into main May 21, 2026
1 of 4 checks passed
@danieljohnmorris
danieljohnmorris deleted the fix/ternary-type-hint branch May 21, 2026 20:28
danieljohnmorris added a commit that referenced this pull request May 21, 2026
Targeted hint on ILO-T003 ternary branch-type mismatch
@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
7575 1 7574 0
View the top 1 failed test(s) by shortest run time
ilo::skill_md::body_is_thin_bootstrap
Stack Traces | 0.006s run time
thread 'body_is_thin_bootstrap' (65130) panicked at tests/skill_md.rs:254:5:
SKILL.md body is 10925 bytes; bootstrap shape should stay well under 8 KB
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant