Stage c/218 records and codemod#310
Conversation
Structurally removes the block-vs-record-literal ambiguity (#215 families C+D) with no lookahead heuristic, per the owner-approved Rust-like model: - `{` in expression position is ALWAYS a block. - record/struct literals use `#{ … }` (anonymous `#{ x: 1 }` and typed `Foo #{ x: 1 }`). - record *patterns* unchanged (pattern position has no block alternative — no ambiguity there). Changes: HASH_LBRACE token (token.ml), `#{` lexer rule (lexer.ml; `#` was previously unused so longest-match is collision-free), both ExprRecord productions rerouted LBRACE -> HASH_LBRACE (parser.mly). Menhir conflicts on origin/main (a45b021): 72 S/R + 10 R/R after: 68 S/R + 7 R/R (-4 / -3) Build clean. BREAKING: legacy `{ … }` record syntax no longer parses; the codemod-migrated repo `.affine` files land in the same PR so the 253/257 gate stays green. Refs #218 #215 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mechanical companion to the `#{` grammar change — 45 in-repo `.affine`
files (stdlib, tests, golden oracles, e2e fixtures, examples) rewritten
from legacy `{ … }` record literals to `#{ … }`.
Method: a sound, convergent codemod that depends ONLY on the new,
unambiguous grammar (never the old ambiguous parser): parse with the
new grammar, and at each parse error insert `#` before the innermost
enclosing record `{`, iterating to a fixed point. Codepoint-correct
(handles non-ASCII). The codemod tooling is intentionally not committed.
Result: `dune runtest` = 257/257 green (the #218 gate), identical to
the pre-change baseline — no regression; `#{` is now the record syntax
across the full test suite.
Out of scope (tracked, per the #218 plan steps 3–4):
- estate-wide `.affine` sweep in other repos;
- ~24 non-gating files the convergent codemod did not auto-migrate
(LR error reported past the record's `}`): conformance/valid/*,
docs/guides/warmup/*, codegen-deno/*, some tests/types/* — plus the
intentional conformance/invalid/* error fixtures and face-syntax
examples which must stay as-is. None are in the 257 gate.
Refs #218 #215
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Closing as superseded by already-merged work. WhyIssue #218 (Rust-like record syntax migration
Issue #218 itself is Evidence
This PR's parser/lexer changes are byte-equivalent (modulo Relationship to PR #312PR #312 is the sibling tooling PR (instrumented parser + codemod) used to generate this migration sweep. Its own body says "do NOT merge into main". Both PRs are now obsolete artefacts from the pre-merge tooling pipeline. ActionClosing without merge. Stale duplicate of #222 + #223. 🤖 Generated with Claude Code |
|
Closing-rationale (since the close was already in flight when I went to close-with-comment): This PR migrates expression-position record literals from Companion PR #312 (the codemod tooling) was also closed as superseded — its body explicitly says "do NOT merge into main". dune test on origin/main is 257/257 (the #218 gate). |
No description provided.