Skip to content

Fix qualified range endpoints and literal recovery - #159

Merged
itsfuad merged 2 commits into
mainfrom
fix/qualified-range-endpoints
Oct 7, 2026
Merged

itsfuad merged 2 commits into
mainfrom
fix/qualified-range-endpoints

Conversation

@itsfuad

@itsfuad itsfuad commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Fixes #157.

  • Parse bare qualified range endpoints without consuming the loop-body brace; retain imported bindings, source locations, and range-entry evidence.
  • Use current grammar (Type.{...}, .{...}, and Enum::Variant with payload) and remove migration-only literal parsing and stored control-header state.
  • Recover missing literal introducers with one local, nesting-aware scanner; preserve enclosing delimiters, following statements, and independent errors.
  • Keep parser-owned BadExpr diagnostics intact in the resolver and publish invalid type evidence in the typechecker. Type-argument diagnostic wording requires parsed AppliedType.TypeArgs evidence.
  • Add parser/semantic/pipeline regressions and executable positive/negative fixtures, update frontend documentation, and install portable investigation/planning skills.
  • Includes author-added backlog documentation in separate commit afc5568; implementation is commit a145d64.

Delivered

Production ownership

  • Production path: parseForStmt -> parseIndexOperand / parseRangeExpr -> Pratt expression parser -> existing binding, typechecking, THIR, MIR, and LLVM owners.
  • recoverBracedLiteral is called by prefix recovery, identifier/qualified-path suffix recovery, and parsed generic-path recovery. It centralizes non-obvious delimiter/body ownership rather than adding a second parser.
  • literalFieldFollows is reused by header disambiguation and argument-comma recovery. Both helpers have current non-test production callers.
  • Reuses existing precedence handlers, parseBracedItemList, registered BadExpr, diagnostic codes, and semantic evidence publication.
  • Removes Parser.isControlHeader, parseExprWithControlHeader, variantLiteralPrecedesControlBody, migration-only literal branches, and the obsolete struct-field pass-through layer. No unused production API or experimental scaffolding remains.

Design and behavior

  • Previously, values::Zero..values::One { ... } could treat the body as a malformed enum payload and cascade into missing delimiter/return diagnostics. Qualified control headers followed by standalone blocks had the same ambiguity.
  • Valid literal braces now have explicit introducers. Recovery carries the caller's delimiter locally; operators inherit it and calls/grouping/indexes/literal values establish their own boundaries.
  • Header recovery requires invalid field-shaped contents and a following body or expression continuation. Adjacent brace groups alone do not classify a literal.
  • Qualified paths receive honest struct/enum correction alternatives; parsing never infers enum identity solely from ::.
  • Preserves node registration/spans, later valid syntax and bindings, independent diagnostics, generic-token splitting, and downstream range/lowering invariants. Unknown-node invariant panics remain intact.
  • Unsupported syntax remains rejected. Diagnostic wording and recovery shape intentionally replace migration-specific handling and redundant semantic cascades.

Validation

Passed on final compiler source, before the documentation-only backlog commit:

go test -count=1 ./internal/frontend/parser ./internal/semantics/resolver ./internal/semantics/typechecker
CCACHE_DISABLE=1 go test -count=1 ./...
go run ./scripts/bundle.go
PEEPER_BIN="$PWD/build/bin/peeper" CCACHE_DISABLE=1 go test -count=1 ./x_test -run '^TestFixtureContracts/(negative_literal_recovery|negative_variant_literal_control_header|runtime_struct_literal_dot|for_qualified_range_endpoints)$'
git diff --check
git diff --cached --check

The focused parser/resolver/typechecker check passed again during read-only review (0.216s / 0.033s / 1.678s). Final targeted bundled fixtures passed in 0.469s.

Earlier Step 7 validation passed before the final diagnostic-only type-argument guard; these results are inherited, not rerun for that guard:

go test -count=1 ./internal/semantics/analysis ./internal/ir/thir ./internal/ir/mir
go test -count=1 ./internal/pipeline -run '^TestPipelineRecordsQualifiedRangeEntryAcrossTargets$'
CCACHE_DISABLE=1 go test -race -count=1 ./...
go vet ./...
PEEPER_BIN="$PWD/build/bin/peeper" CCACHE_DISABLE=1 go test -count=1 ./x_test

Full bundled fixtures passed in isolation (18.405s). Pipeline regression covers 386/amd64 binding, imported ownership, types, guaranteed entry, missing-return behavior, and lowering/object contracts. Disposable peeper check probes exercised targeted literal diagnostics and valid adjacent-block controls.

At PR creation, preflight verified remote main was 03a3272, reviewed both included commits, and confirmed implementation-source diff checks pass. Whole-branch git diff main...HEAD --check reports the two-space Markdown line breaks in the author's separate TODO.md commit; the same check excluding TODO.md passes. No compiler source changed after validation. Cross-platform native execution subsequently passed in PR and post-merge CI.

Diff sanity

  • Peeper code review: Standards 0 findings; Spec 0 findings.
  • No unrelated production changes, duplicate semantic decisions, dead code, or temporary/debug instrumentation introduced.
  • Shared recovery helpers satisfy reuse and invariant-protection rules. Documentation records current grammar and actual recovery ownership.
  • Author confirmed manual review-marker removal; the agent did not remove it.

Risks and follow-up

  • Body ownership and enclosing delimiters must remain protected; do not restore stored header mode or indiscriminate two-brace lookahead.
  • Run bundle-dependent fixtures separately from other expensive suites: an earlier concurrent run hit missing/invalid runtime-archive evidence; isolated reruns passed.
  • Related existing follow-up: Add LSP struct literal snippet completion after Type. #134 (LSP struct-literal snippets for current syntax). No new tactical bridge introduced.
  • Milestone: 0.2 Language Foundations. Roadmap project sync is complete.
  • Merge requires passing applicable CI and approval from a non-author human collaborator.

@itsfuad itsfuad added this to the 0.2 Language Foundations milestone Oct 7, 2026
@itsfuad
itsfuad merged commit 29eac4d into main Oct 7, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Disambiguate qualified range endpoints from loop bodies

1 participant