diff --git a/CHANGELOG.md b/CHANGELOG.md index 782b4de5c5..94395faecf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - Remove obsolete built-in project templates and the "rescript init" functionality. This will be replaced by the create-rescript-app project that is maintained separately. - Parse the attributes of labelled argument to the pattern attributes of argument instead of function. - Made pinned dependencies transitive: if *a* is a pinned dependency of *b* and *b* is a pinned dependency of *c*, then *a* is implicitly a pinned dependency of *c*. This change is only breaking if your build process assumes non-transitivity. +- Curried after uncurried is not fused anymore: `(. x) => y => 3` is not equivalent to `(. x, y) => 3` anymore. It's instead equivalent to `(. x) => { y => 3 }`. #### :nail_care: Polish diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 45f037db63..9abdaf92fa 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -56050,7 +56050,8 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl = (ParsetreeViewer.rewriteUnderscoreApply e) cmtTbl | Pexp_fun _ | Pexp_newtype _ -> printArrow ~isUncurried:false e - | Pexp_record ([({txt = Ldot (Ldot (Lident "Js", "Fn"), name)}, funExpr)], None) + | Pexp_record + ([({txt = Ldot (Ldot (Lident "Js", "Fn"), name)}, funExpr)], None) when String.length name >= 1 && name.[0] = 'I' -> printArrow ~isUncurried:true funExpr | Pexp_record (rows, spreadExpr) -> diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index 5312f69e4e..25c87c8fff 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -56050,7 +56050,8 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl = (ParsetreeViewer.rewriteUnderscoreApply e) cmtTbl | Pexp_fun _ | Pexp_newtype _ -> printArrow ~isUncurried:false e - | Pexp_record ([({txt = Ldot (Ldot (Lident "Js", "Fn"), name)}, funExpr)], None) + | Pexp_record + ([({txt = Ldot (Ldot (Lident "Js", "Fn"), name)}, funExpr)], None) when String.length name >= 1 && name.[0] = 'I' -> printArrow ~isUncurried:true funExpr | Pexp_record (rows, spreadExpr) -> diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index afb38b11cd..7519def19d 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -231912,7 +231912,8 @@ and printExpression ~customLayout (e : Parsetree.expression) cmtTbl = (ParsetreeViewer.rewriteUnderscoreApply e) cmtTbl | Pexp_fun _ | Pexp_newtype _ -> printArrow ~isUncurried:false e - | Pexp_record ([({txt = Ldot (Ldot (Lident "Js", "Fn"), name)}, funExpr)], None) + | Pexp_record + ([({txt = Ldot (Ldot (Lident "Js", "Fn"), name)}, funExpr)], None) when String.length name >= 1 && name.[0] = 'I' -> printArrow ~isUncurried:true funExpr | Pexp_record (rows, spreadExpr) -> diff --git a/res_syntax/src/res_core.ml b/res_syntax/src/res_core.ml index 8be8259e91..d02320e101 100644 --- a/res_syntax/src/res_core.ml +++ b/res_syntax/src/res_core.ml @@ -1515,6 +1515,18 @@ and parseEs6ArrowExpression ?(arrowAttrs = []) ?(arrowStartPos = None) ?context in Parser.eatBreadcrumb p; let endPos = p.prevEndPos in + let body = + match parameters with + | TermParameter {uncurried = true} :: _ + when match body.pexp_desc with + | Pexp_fun _ -> true + | _ -> false -> + { + body with + pexp_attributes = makeBracesAttr body.pexp_loc :: body.pexp_attributes; + } + | _ -> body + in let arrowExpr, _arity = List.fold_right (fun parameter (expr, arity) -> diff --git a/res_syntax/tests/parsing/grammar/expressions/expected/uncurried.res.txt b/res_syntax/tests/parsing/grammar/expressions/expected/uncurried.res.txt index b31f86e971..ccfd5dc7c7 100644 --- a/res_syntax/tests/parsing/grammar/expressions/expected/uncurried.res.txt +++ b/res_syntax/tests/parsing/grammar/expressions/expected/uncurried.res.txt @@ -9,9 +9,13 @@ let f = (({ Js.Fn.I1 = (fun a -> - ((fun b -> (({ Js.Fn.I1 = (fun c -> ((fun d -> ())[@attr4 ])) }) + ((fun b -> + (({ + Js.Fn.I1 = + (fun c -> ((fun d -> ())[@ns.braces ][@attr4 ])) + }) [@attr3 ])) - [@attr2 ])) + [@ns.braces ][@attr2 ])) }) [@attr ]) let f = diff --git a/res_syntax/tests/printer/expr/asyncAwait.res b/res_syntax/tests/printer/expr/asyncAwait.res index 1e67410f7f..36f59137bc 100644 --- a/res_syntax/tests/printer/expr/asyncAwait.res +++ b/res_syntax/tests/printer/expr/asyncAwait.res @@ -115,9 +115,5 @@ let b3 = await (foo->bar(~arg)) let b4 = await (foo.bar.baz) let c1 = @foo x => @bar y => x + y - -// This is not idempotent: -// let c2 = (. x) => y => x+y - -let c2 = (. x, y) => x+y +let c2 = (. x) => y => x+y let c3 = (. x) => @foo y => x+y diff --git a/res_syntax/tests/printer/expr/expected/asyncAwait.res.txt b/res_syntax/tests/printer/expr/expected/asyncAwait.res.txt index 32a489d36c..f99ce11883 100644 --- a/res_syntax/tests/printer/expr/expected/asyncAwait.res.txt +++ b/res_syntax/tests/printer/expr/expected/asyncAwait.res.txt @@ -137,9 +137,5 @@ let b3 = await foo->bar(~arg) let b4 = await foo.bar.baz let c1 = @foo x => @bar y => x + y - -// This is not idempotent: -// let c2 = (. x) => y => x+y - -let c2 = (. x, y) => x + y -let c3 = (. x) => @foo y => x + y +let c2 = (. x) => {y => x + y} +let c3 = (. x) => {@foo y => x + y}