Skip to content

Fix: dot-index reattaches to multi-arg call result#583

Closed
danieljohnmorris wants to merge 1 commit into
mainfrom
fix/call-dot-index
Closed

Fix: dot-index reattaches to multi-arg call result#583
danieljohnmorris wants to merge 1 commit into
mainfrom
fix/call-dot-index

Conversation

@danieljohnmorris
Copy link
Copy Markdown
Collaborator

Summary

Closes ILO-52. spl s d .1 (where both args are bare variable references) previously parsed as Call(spl, [Ref(s), Index(Ref(d), 1)]) — the .1 was stolen by the bare-ident arm of parse_atom_body before the outer call loop could claim it.

Root cause

parse_atom_body's bare-Ident branch unconditionally called parse_field_chain, greedily consuming .N even while inside the arg collection loop of an outer call.

Fix

Added an in_call_args: bool context flag to Parser. Set to true for the duration of every greedy arg loop in parse_call_or_atom and parse_call_arg (save/restore pattern). In parse_atom_body's bare-ident branch, when in_call_args is true, field-chain consumption is suppressed — the outer parse_field_chain call at the end of each loop then attaches the .N to the assembled call result.

Before / After

spl s d .1

Before: Call { function: "spl", args: [Ref("s"), Index { object: Ref("d"), index: 1 }] }
After:  Index { object: Call { function: "spl", args: [Ref("s"), Ref("d")] }, index: 1 }
num spl s d .1

Before: Call { function: "num", args: [Call { function: "spl", args: [Ref("s"), Index { object: Ref("d"), index: 1 }] }] }
After:  Call { function: "num", args: [Index { object: Call { function: "spl", args: [Ref("s"), Ref("d")] }, index: 1 }] }

Verified no-regression cases

  • spl "1.2.3" "." .1 — literal last arg (already worked)
  • (spl s d).1 — explicit parens (always worked)
  • x.1 standalone — bare ident not in call args (still works)
  • at xs 0 .1 — literal last arg (already worked)

Changes

  • src/parser/mod.rsin_call_args flag + save/restore in 4 arg loops + suppression in bare-ident atom branch
  • tests/parser_call_index.rs — new regression test file covering the broken and no-regression cases
  • examples/call-dot-index.ilo — new example demonstrating the fix
  • examples/call-result-dot-index.ilo — removed the now-obsolete "heads-up" note about bare-ident last args

🤖 Generated with Claude Code

…are ident

Closes ILO-52. Previously `spl s d .1` parsed as Call(spl, [s, Index(d,1)])
because parse_atom greedily attached .N to bare Ref idents. Now suppressed
inside call-args context — outer parse_field_chain wraps the whole call.
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
218 1 217 0
View the top 1 failed test(s) by shortest run time
ilo::codegen::fmt::tests::idempotent_example_04
Stack Traces | 0.011s run time
thread 'codegen::fmt::tests::idempotent_example_04' (30295) panicked at src/codegen/fmt.rs:716:9:
parse errors in test: [ParseError { code: "ILO-P003", position: 42, span: Span { start: 124, end: 138 }, message: "expected `;`, got text `\"Notification\"`", hint: None }]
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.

@danieljohnmorris
Copy link
Copy Markdown
Collaborator Author

Superseded by #572 (already merged — same fix for call-result dot-index reattach)

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