Harden the Parsetree0 PPX bridge - #8561
Open
cristianoc wants to merge 2 commits into
Open
Conversation
The v0 bridge (ast_mapper_to0 / ast_mapper_from0) had several fidelity bugs that surfaced whenever code passed through an external PPX: - the internal res.async marker leaked back into the program as a real attribute after decoding; - attributes on an arrow-type node were merged into the argument's attribute list on the way back, which crashed the formatter with a stack overflow; the two lists are now kept separable with an internal _res.arrow_node_attrs marker, and the arrow_type viewer additionally always consumes the head argument so it can never return its input as the "return type"; - the await node's own attributes were dropped entirely (losing e.g. @outer in "@outer await (@inner e)" and res.braces on async bodies); res.await now serves as the boundary between await-node attributes and inner-expression attributes; - JSX container elements were rebuilt without a closing tag, printing unclosed elements; a closing tag matching the opening tag is now synthesized; - PPX-emitted OCaml-style `function | p -> e` hit assert false; it is now desugared to `fun x -> match x with ...` like the OCaml parser would. Marshaled current-parsetree streams (-as-pp, res_parser -print binary, Ast_mapper.apply_lazy) now carry their own magic numbers (ResImpl01300/ResIntf01300); the Caml1999M022/N022 pair is reserved for the frozen Parsetree0 wire format that external PPXes rely on. Round-trip sweep over all 350 syntax test files: 37 diverging files before, 21 after, no regressions; every arrows/functions/async/await file now round-trips byte-identically. New ast-mapping corpus file FunctionsAndArrows.res pins the constructs, and a unit test covers the function-cases desugaring. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
cristianoc
force-pushed
the
codex/harden-parsetree0-bridge
branch
from
August 18, 2026 12:13
74abf0e to
efc0cc5
Compare
Signed-off-by: Cristiano Calcagno <cristianoc@users.noreply.github.com>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## codex/function-arity-inclusion #8561 +/- ##
==================================================================
+ Coverage 75.54% 75.59% +0.04%
==================================================================
Files 476 476
Lines 62732 62759 +27
==================================================================
+ Hits 47393 47443 +50
+ Misses 15339 15316 -23
🚀 New features to boost your workflow:
|
rescript
@rescript/darwin-arm64
@rescript/darwin-x64
@rescript/linux-arm64
@rescript/linux-x64
@rescript/runtime
@rescript/win32-x64
commit: |
cristianoc
marked this pull request as ready for review
August 18, 2026 13:01
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
functionexpressions instead of reachingassert falseCaml1999M022andCaml1999N022exclusive to the frozen external-PPX wire formatPexp_functioninputWhy
The current AST and frozen Parsetree0 no longer have identical structure, but parts of the bridge still treated them as if they did. In particular, a single v0 attribute list sometimes represented attributes from two current-AST nodes. This leaked the internal
res.asyncmarker, dropped or relocated await and arrow attributes, and could make the formatter recurse indefinitely. JSX container reconstruction also omitted its closing tag, while a v0Pexp_functionemitted by a PPX crashed during conversion.The bridge now makes those boundaries explicit and keeps the frozen PPX protocol distinct from streams that marshal the evolving current parsetree.
Stack
This PR is stacked on #8559. Review the single commit introduced by this branch; the base PR contains the prerequisite function-arity changes.
Validation
make test