Skip to content

Commit 611d3a8

Browse files
authored
Parser/Printer: unify uncurried functions of arity 0, and of arity 1 taking unit. (#5825)
* Test: don't emit arity zero from the parser. * Clean up: remove "(u)" encoding for uncurried unariy application. * Update CHANGELOG.md * Use `res.uapp` for uncurried app attribute coming from the parser. * Clean up test. * rename * Update CHANGELOG.md
1 parent 2209d76 commit 611d3a8

28 files changed

+356
-221
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
- Add support for partial application of uncurried functions: with uncurried application one can provide a
2121
subset of the arguments, and return a curried type with the remaining ones https://github.com/rescript-lang/rescript-compiler/pull/5805
2222
- Add support for uncurried externals https://github.com/rescript-lang/rescript-compiler/pull/5815 https://github.com/rescript-lang/rescript-compiler/pull/5819
23+
- Parser/Printer: unify uncurried functions of arity 0, and of arity 1 taking unit. There's now only arity 1 in the source language. https://github.com/rescript-lang/rescript-compiler/pull/5825
24+
2325

2426
#### :boom: Breaking Change
2527

@@ -32,7 +34,6 @@ subset of the arguments, and return a curried type with the remaining ones https
3234
- 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 }`.
3335
Also, `(. int) => string => bool` is not equivalen to `(. int, string) => bool` anymore.
3436
These are only breaking changes for unformatted code.
35-
- Distinguish between uncurried type `(. ()) => int`, whch takes 0 arguments, and `(. unit) => int` which takes 1 argument of type `unit` https://github.com/rescript-lang/rescript-compiler/pull/5821
3637

3738
#### :bug: Bug Fix
3839

jscomp/frontend/ast_attributes.ml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,12 @@ let iter_process_bs_string_or_int_as (attrs : Parsetree.attributes) =
305305
_;
306306
};
307307
]
308-
when Ast_utf8_string_interp.parse_processed_delim delim_ <> None -> (
308+
when Ast_utf8_string_interp.parse_processed_delim delim_
309+
<> None -> (
309310
let delim =
310-
match Ast_utf8_string_interp.parse_processed_delim delim_ with
311+
match
312+
Ast_utf8_string_interp.parse_processed_delim delim_
313+
with
311314
| None -> assert false
312315
| Some delim -> delim
313316
in
@@ -338,6 +341,9 @@ let locg = Location.none
338341
let is_bs (attr : attr) =
339342
match attr with { Location.txt = "bs"; _ }, _ -> true | _ -> false
340343

344+
let is_res_uapp (attr : attr) =
345+
match attr with { Location.txt = "res.uapp"; _ }, _ -> true | _ -> false
346+
341347
let bs_get : attr = ({ txt = "bs.get"; loc = locg }, Ast_payload.empty)
342348

343349
let bs_get_index : attr =

jscomp/frontend/ast_attributes.mli

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ val is_bs : attr -> bool
7272
(* val is_optional : attr -> bool
7373
val is_bs_as : attr -> bool *)
7474

75+
(* Attribute for uncurried application coming from the ReScript parser *)
76+
val is_res_uapp : attr -> bool
77+
7578
val bs_get : attr
7679

7780
val bs_get_index : attr

jscomp/frontend/ast_exp_apply.ml

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,9 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp)
158158
})
159159
| _ -> (
160160
match
161-
( Ext_list.exclude_with_val f_.pexp_attributes
162-
Ast_attributes.is_bs,
161+
( Ext_list.exclude_with_val f_.pexp_attributes (fun a ->
162+
Ast_attributes.is_bs a
163+
|| Ast_attributes.is_res_uapp a),
163164
f_.pexp_desc )
164165
with
165166
| Some other_attributes, Pexp_apply (fn1, args) ->
@@ -173,8 +174,8 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp)
173174
fn1.pexp_attributes;
174175
{
175176
pexp_desc =
176-
Ast_uncurry_apply.uncurry_fn_apply e.pexp_loc self fn1
177-
((Nolabel, a) :: args);
177+
Ast_uncurry_apply.uncurry_fn_apply ~arity0:(op = "|.")
178+
e.pexp_loc self fn1 ((Nolabel, a) :: args);
178179
pexp_loc = e.pexp_loc;
179180
pexp_attributes = e.pexp_attributes @ other_attributes;
180181
}
@@ -183,7 +184,8 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp)
183184
Uncurried unary application *)
184185
{
185186
pexp_desc =
186-
Ast_uncurry_apply.uncurry_fn_apply e.pexp_loc self f
187+
Ast_uncurry_apply.uncurry_fn_apply ~arity0:false
188+
e.pexp_loc self f
187189
[ (Nolabel, a) ];
188190
pexp_loc = e.pexp_loc;
189191
pexp_attributes = e.pexp_attributes;
@@ -283,11 +285,25 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp)
283285
match
284286
Ext_list.exclude_with_val e.pexp_attributes Ast_attributes.is_bs
285287
with
286-
| None -> default_expr_mapper self e
287288
| Some pexp_attributes ->
288289
{
289290
e with
290291
pexp_desc =
291-
Ast_uncurry_apply.uncurry_fn_apply e.pexp_loc self fn args;
292+
Ast_uncurry_apply.uncurry_fn_apply ~arity0:true e.pexp_loc
293+
self fn args;
292294
pexp_attributes;
293-
}))
295+
}
296+
| None -> (
297+
match
298+
Ext_list.exclude_with_val e.pexp_attributes
299+
Ast_attributes.is_res_uapp
300+
with
301+
| Some pexp_attributes ->
302+
{
303+
e with
304+
pexp_desc =
305+
Ast_uncurry_apply.uncurry_fn_apply ~arity0:false
306+
e.pexp_loc self fn args;
307+
pexp_attributes;
308+
}
309+
| None -> default_expr_mapper self e)))

jscomp/frontend/ast_uncurry_apply.ml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ let opaque_full_apply ~loc (e : exp) : Parsetree.expression_desc =
4444
[ (Nolabel, e) ],
4545
Typ.any ~loc () )
4646

47-
let generic_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression)
48-
(args : Ast_compatible.args) (cb : loc -> exp -> exp) =
47+
let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper)
48+
(obj : Parsetree.expression) (args : Ast_compatible.args)
49+
(cb : loc -> exp -> exp) =
4950
let obj = self.expr self obj in
5051
let args =
5152
Ext_list.map args (fun (lbl, e) ->
@@ -57,7 +58,8 @@ let generic_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression)
5758
match args with
5859
| [
5960
(Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) });
60-
] ->
61+
]
62+
when arity0 ->
6163
[]
6264
| _ -> args
6365
in
@@ -128,9 +130,9 @@ let method_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression)
128130
])
129131
args)
130132

131-
let uncurry_fn_apply loc self fn args =
132-
generic_apply loc self fn args (fun _ obj -> obj)
133+
let uncurry_fn_apply ~arity0 loc self fn args =
134+
generic_apply ~arity0 loc self fn args (fun _ obj -> obj)
133135

134136
let property_apply loc self obj name args =
135-
generic_apply loc self obj args (fun loc obj ->
137+
generic_apply ~arity0:true loc self obj args (fun loc obj ->
136138
Exp.send ~loc obj { txt = name; loc })

jscomp/frontend/ast_uncurry_apply.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
(* TODO: the interface is not reusable, it depends on too much context *)
2626

2727
val uncurry_fn_apply :
28+
arity0:bool ->
2829
Location.t ->
2930
Bs_ast_mapper.mapper ->
3031
Parsetree.expression ->

jscomp/test/UncurriedExternals.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ var te = (function (prim) {
3232
RE_EXN_ID: "Not_found"
3333
});
3434

35+
var tcr = {};
36+
3537
var StandardNotation = {
3638
dd: dd,
3739
h: h,
@@ -40,7 +42,8 @@ var StandardNotation = {
4042
mf: mf,
4143
tg: tg,
4244
tc: tc,
43-
te: te
45+
te: te,
46+
tcr: tcr
4447
};
4548

4649
function dd$1(param) {
@@ -74,6 +77,8 @@ var te$1 = (function (prim) {
7477
RE_EXN_ID: "Not_found"
7578
});
7679

80+
var tcr$1 = {};
81+
7782
exports.StandardNotation = StandardNotation;
7883
exports.dd = dd$1;
7984
exports.h = h$1;
@@ -83,4 +88,5 @@ exports.mf = mf$1;
8388
exports.tg = tg$1;
8489
exports.tc = tc$1;
8590
exports.te = te$1;
91+
exports.tcr = tcr$1;
8692
/* h Not a pure module */

jscomp/test/UncurriedExternals.res

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ module StandardNotation = {
2323

2424
external toException: (. exn) => exn = "%identity"
2525
let te = toException(. Not_found)
26+
27+
@obj external ccreate : (. unit) => string = ""
28+
let tcr = ccreate(.)
2629
}
2730

2831
@@uncurried
@@ -51,3 +54,6 @@ let tc = copy("abc")
5154

5255
external toException: exn => exn = "%identity"
5356
let te = toException(Not_found)
57+
58+
@obj external ucreate : unit => string = ""
59+
let tcr = ucreate()

jscomp/test/reactTestUtils.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@ var Caml_option = require("../../lib/js/caml_option.js");
77
var TestUtils = require("react-dom/test-utils");
88

99
function act(func) {
10-
var reactFunc = function () {
10+
var reactFunc = function (param) {
1111
Curry._1(func, undefined);
1212
};
1313
TestUtils.act(reactFunc);
1414
}
1515

1616
function actAsync(func) {
17-
return TestUtils.act(function () {
17+
return TestUtils.act(function (param) {
1818
return Curry._1(func, undefined);
1919
});
2020
}

jscomp/test/uncurried_cast.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ var StandardNotation = {
7676
anInt: anInt
7777
};
7878

79-
function testRaise$1() {
79+
function testRaise$1(param) {
8080
return raise({
8181
RE_EXN_ID: E
8282
});

0 commit comments

Comments
 (0)