fix: persona-diagnostic batch 2 (cross-language slips)#300
Merged
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
039d46f to
5c8f599
Compare
`AND a b` lex-fails at the leading capital with a bare `unexpected token 'A'` and `OR a b` cascades into a downstream parse error because `O` lexes as the OptType sigil. Personas (qa-tester, scientific-researcher rerun3) hit this when reaching for boolean operators from Python/JavaScript/Pascal. Add a forward-scan of consecutive uppercase letters at fresh-expression position; when the resulting word matches a known logical keyword (`AND`, `OR`, `NOT`), emit ILO-L001 with a suggestion pointing at the canonical `&` / `|` / `!` prefix forms. Type position is left alone: `f x:OR n n>n` is the compact form of `O R n n` (Optional of Result), which is valid ilo. The guard checks the previous token for `:`, `>`, or a sigil before firing, so intentional compact-type composition keeps working. The new path is also gated on fresh-position (no preceding flush ident and no post-dot context) so `fooAND` stays an L003 mid-ident camel error and `r.OR` stays a JSON post-dot field access.
Four diagnostic improvements at the parser level, each addressing
persona-friction patterns from rerun3 logs.
`=<a b` / `=>a b` compound-prefix (qa-tester): the parser used to
consume `=` as its own prefix-eq then fail at the second operand with
a misleading "expected expression, got LBrace" deep in the
expression. Detect `Eq` followed immediately by `Less`/`Greater`
in parse_prefix_binop and surface ILO-P003 with a suggestion pointing
at the single-token `<=` / `>=` form. `!<` / `!>` are
deliberately excluded; `!cond{body}` is a valid negated guard.
`fn p:t>r;body` lambda at expression position (qa-tester,
scientific-researcher): KwFn used to fall through to a bare
"expected expression, got KwFn". Add a lambda_keyword_message
helper covering `fn` and `def`, called from parse_atom's fallback
arm. Hint points at ilo's parenthesised inline-lambda form
`(x:n>n;+x 1)`.
`main:>n;body` no-param signature shape (qa-tester): the colon-then-
greater pattern after the fn name used to surface as
"expected Greater, got Colon". Add an explicit check in parse_fn_decl
after register_user_fn when params is empty, with a hint pointing at
`name>return;body`.
Multi-line function/loop/guard body (qa-tester, devops-sre, pdf-analyst,
html-scraper, all rerun3): newlines collapse to `;` at the lexer, so
`@k kws\n body` becomes `@k kws;body` and the foreach's required
`{` lands on a `;`. Extend the generic expect() helper so that
`expected LBrace, got Semi` carries a hint about single-line bodies
and braced blocks. Doesn't change any existing error code or message
text, only adds the hint.
Personas (qa-tester, scientific-researcher rerun3) write
`cond{^"err"}` expecting early-return semantics, but a braced
conditional in ilo runs the body and discards its value. The shape
parses cleanly and even runs successfully, so the failure mode is
silent: the program proceeds with whatever follows, never returning the
intended error.
Extend collect_hints to accept the parsed Program and walk it
recursively, looking for a `Stmt::Guard { braceless: false, .. }`
whose body's tail statement is a `Stmt::Expr(Expr::Err(_) |
Expr::Ok(_))`. Recurses through Guard else_body, ForEach/ForRange/
While bodies, and Match arm bodies. Emits a single hint per run pointing
at the canonical braceless guard form `cond ^"err"` or the explicit
`{ret ^"err"}` wrapper.
Test coverage: positive cases for Err and Ok in guard tails, negative
cases for braceless guards (which already return) and explicit `ret`
forms (which already propagate), plus nested-walker coverage for the
ForEach and Match-arm body shapes.
Also strip `--` line-comment contents in warn_cross_language_syntax,
not just string literals. Without this, comments mentioning `->` /
`&&` / `||` / `//` illustratively (e.g. examples that explain
ilo's non-use of these tokens) triggered a false-positive
cross-language warning. Reuses the existing
strip_string_and_comment_contents helper.
Pins the corrected forms our new parser hints suggest, so the examples_engines harness exercises them across tree, VM, and Cranelift as cross-engine regression coverage. Five end-to-end run/out pairs: - main: combines sum-plus-one (foreach with braced body), forty-two (no-param signature), plus-one (inline lambda) - abs-check 7: braceless guard returns ok value - abs-check -3: braceless guard returns err and exits 1 - lte 3 5 / gte 3 5: single-token comparisons Header comment documents each cross-language slip alongside the canonical ilo form, so an agent dumping the file gets the friction map for free.
SPEC.md gets a new "Cross-language gotchas" subsection under Identifier syntax, with a six-row table mapping each known slip (AND/OR/NOT, compound prefix, fn lambda, main:> sig, multi-line body, discarded braced-cond) to its canonical ilo form and the error code that surfaces. build.rs regenerates ai.txt from SPEC.md, so the same table lands in the compact spec. skills/ilo/SKILL.md gets six new entries appended to Common Mistakes, mirroring the SPEC table at the load-bearing summary level so an agent dumping the skill prompt gets the friction map before writing code. Site docs deliberately untouched: the in-flight doc-audit PR #290 already covers reference/error-codes.md and friends, and a parallel edit here would create avoidable merge conflict.
5c8f599 to
2902281
Compare
6 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
Six diagnostic-only improvements addressing persona-friction patterns from rerun3 logs. Each is a cross-language slip that previously surfaced as a bare or misleading parse error; each now emits a friendly hint pointing at the canonical ilo form, so the agent's first retry should be the right one.
Manifesto framing: every friendly hint shaves the cost of one wrong follow-up message. The cumulative savings across these six shapes is meaningful because they're concentrated in early-program-writing turns where retries are expensive.
What's in the diff
Five commits, one logical change each:
ILO-L001with a suggestion pointing at&/|/!. Type position (f x:OR n n>n→O R n n) is left untouched via a prev-token guard.=<a b/=>a bcompound-prefix → suggest<=/>=single token (ILO-P003).fn p:t>r;bodyat expression position → suggest parenthesised inline lambda(p:t>r;body)(ILO-P009).main:>n;bodyno-param signature → suggestmain>n;body(no:before>) (ILO-P003).expected LBrace, got Semimulti-line-body confusion → hint about ilo's single-line;-separated body rule.cond{^\"err\"}runs and discards the body value silently. Added a post-parse AST walker tocollect_hints_with_programthat detects guard bodies whose tail expression isExpr::Err(_)/Expr::Ok(_), recursing through nested ForEach / Match-arm / While bodies. Hint points at the bracelesscond ^\"err\"early-return form. Also fixes a pre-existing false positive inwarn_cross_language_syntax: comments mentioning->/&&/||///illustratively no longer trigger the warning.skills/ilo/SKILL.mdCommon Mistakes. Site docs deliberately untouched to avoid collision with the in-flight doc-audit PR docs: SPEC drift fix for v0.11.2 + load-bearing SKILL.md #290.Items dropped and deferred
sin=42builtin shadow) dropped: already covered by the in-flightfix/builtin-shadow-flat-freqworktree (extendsBuiltin::is_builtingating toparse_letandparse_decl). The fix there is broader and more correct (gates against ALL builtin names, not just trig/log/exp).-parse-error column off-by-one) parked: no clean repro from the original persona log entry. Filed inilo_assessment_feedback.mdParked section for revisit when a concrete failing snippet shows up.Repro before/after
Item 2 —
AND a b:Item 5 —
=<d 0{...}:Item 6 —
f=fn x:n>n;+x 1:Item 7 —
main:>n;42:Item 9 —
@k xs;+k 1:Item 4 —
<x 0{^\"err\"};~x(runs cleanly, silently discards^\"err\"):Test plan
cargo test --release --features cranelift— all 3013 lib + 199 example + integration tests pass, 0 failurescargo fmt --checkcleancargo clippy --release --features cranelift --all-targetscleanFollow-ups
-parse-error column) needs a concrete repro; logged in Parked.