You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make a function's locally abstract types part of the function node
Replace the Pexp_newtype wrapper chains that the parser built for
(type t, x) => ... arrow syntax with a structural field on the function
node: Pexp_fun.newtypes carries each newtype name with its own
attributes, hoisted in front of the value parameters as before.
Pexp_newtype remains solely as the desugaring of [let f: type a. ...]
annotations and for PPX-authored trees.
Fidelity fixes visible in the formatter:
- Attributes keep their association with their type parameter group:
(@attr type t, x, @attr2 type s, y) round-trips as written instead of
printing @attr @attr2 on the function.
- Comments written next to a type parameter travel with it to the
hoisted group instead of migrating onto the following value parameter.
- Attributes written in front of the arrow now live on the function
node, so built-in attribute processing (e.g. @this) sees them on
type-first functions; previously they sat inert on the wrapper node.
Typing follows the upstream OCaml 5.x design: the newtype machinery is
extracted into a reusable type_newtype helper (mirroring OCaml's helper
of the same name) and the function case peels one newtype at a time,
mimicking the typing of the former wrapper chain; the typedtree output
is bit-identical to before.
The v0 PPX bridge expands the field back into a wrapper chain around
Function$: each wrapper carries its own newtype's attributes, and the
outermost wrapper separates function-node attributes from the first
newtype's attributes with an internal _res.newtype_attrs marker (no
marker means node attributes only, matching the historical wire).
Newtype-free programs are wire byte-identical; for functions with
newtypes the deltas are confined to wrapper-node locations and, for the
rare attributed groups, per-wrapper attribute placement. Identity-PPX
round-trips are AST-exact, verified against the previous compiler.
Also: jsx_v4 and bs_builtin_ppx now carry newtypes (and their
attributes) through their function rebuilds instead of dropping them,
the sexp AST debugger emits the field, and dead parser plumbing
(fundef param attrs/p_pos, arrow_start_pos, make_newtypes ~attrs) is
removed.
Signed-Off-By: Cristiano Calcagno <cristianoc@users.noreply.github.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -29,6 +29,7 @@
29
29
30
30
- Fix argument evaluation order when a function call is inlined: the beta reducer stacked argument bindings in reverse parameter order, so the last argument was evaluated first when arguments could not be substituted directly. https://github.com/rescript-lang/rescript/pull/8572
31
31
- Preserve parentheses around multiplication, division, and modulo expressions used as exponents. https://github.com/rescript-lang/rescript/pull/8550
32
+
- Make a function's locally abstract types (`(type t, x) => ...`) part of the function AST node instead of a chain of wrapper nodes. Fixes the formatter dropping the association of attributes with their `type` group (`(@attr type t, x, @attr2 type s, y)` used to print as `@attr @attr2` on the function) and comments written next to a type parameter migrating onto the following value parameter. https://github.com/rescript-lang/rescript/pull/8574
32
33
- Enforce function arity in interface/module inclusion and type coercion. Previously a curried implementation (e.g. `int => int => int`) could satisfy an uncurried interface (`(int, int) => int`) or be coerced to it, which could miscompile calls made through the interface type. Such mismatches are now compile errors with an explanatory hint. https://github.com/rescript-lang/rescript/pull/8559
33
34
- Fix termination-analysis false positives for functions whose progress flows through un-annotated helpers: collecting the callees of a function binding was accidentally disabled in 2024 (the collection guard required a node shape that uncurried code never produces), so helpers calling `@progress` functions were no longer added to the function table. https://github.com/rescript-lang/rescript/pull/8568
34
35
- Fix default values of optional parameters being computed at the wrong time for curried functions: in `(~x=default, y) => (~z=default, w) => ...`, `x`'s default was only computed when the *inner* function was applied. Each default is now computed when its own parameter group is applied. https://github.com/rescript-lang/rescript/pull/8568
0 commit comments