Skip to content

Commit 1a289c2

Browse files
committed
Treat foo(. ) as empty application if all arguments are optional.
When all the processed arguments to the function are ignored (hence optional), and no arguments are ignored (so no mandatory labelled), it means the uncurried function only has optional arguments. - If the uncurried type of the function had an unlabelled arg, then it would be caught by the unit application, so it would be a non-ignored argument. But this is not possible as all the argiments are ignored. - If it had a labelled mandatory argument, then either it would be non-ignored, or omitted, but both cases are excluded. - It follows that the type only has optional arguments, and that the unit argument was the only argument supplied. The new mechanism does not kick in when some legit argument is passed alongside the unit. And noes not interfere with cases where the function expects a legitimate unit argument.
1 parent d314f94 commit 1a289c2

File tree

3 files changed

+68
-11
lines changed

3 files changed

+68
-11
lines changed

jscomp/ml/typecore.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3019,7 +3019,7 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex
30193019
match has_uncurried_type t with
30203020
| Some (arity, _) ->
30213021
let newarity = arity - nargs in
3022-
let fully_applied = newarity = 0 in
3022+
let fully_applied = newarity <= 0 in
30233023
if uncurried && not fully_applied then
30243024
raise(Error(funct.exp_loc, env,
30253025
Uncurried_arity_mismatch (t, arity, List.length sargs)));
@@ -3046,6 +3046,10 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex
30463046
| _ -> collect_args ())
30473047
else
30483048
collect_args ()
3049+
| [(Nolabel, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)})]
3050+
when uncurried && omitted = [] && List.length args = List.length !ignored ->
3051+
(* foo(. ) treated as empty application if all args are optional (hence ignored) *)
3052+
type_unknown_args max_arity args omitted ty_fun []
30493053
| (l1, sarg1) :: sargl ->
30503054
let (ty1, ty2) =
30513055
let ty_fun = expand_head env ty_fun in

jscomp/test/uncurried_default.args.js

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,42 @@ var partial = Curry._1((function (param) {
2020

2121
var total = withOpt(10, 3)(4, 11);
2222

23+
function foo1(xOpt, y) {
24+
var x = xOpt !== undefined ? xOpt : 3;
25+
return x + y | 0;
26+
}
27+
28+
var x = 3;
29+
30+
var r1 = x + 11 | 0;
31+
32+
function foo2(y, xOpt, zOpt) {
33+
var x = xOpt !== undefined ? xOpt : 3;
34+
var z = zOpt !== undefined ? zOpt : 4;
35+
return (x + y | 0) + z | 0;
36+
}
37+
38+
var r2 = foo2(11, undefined, undefined);
39+
40+
function foo3(xOpt, yOpt) {
41+
var x = xOpt !== undefined ? xOpt : 3;
42+
var y = yOpt !== undefined ? yOpt : 4;
43+
return x + y | 0;
44+
}
45+
46+
var r3 = foo3(undefined, undefined);
47+
2348
var StandardNotation = {
2449
withOpt: withOpt,
2550
testWithOpt: testWithOpt,
2651
partial: partial,
27-
total: total
52+
total: total,
53+
foo1: foo1,
54+
r1: r1,
55+
foo2: foo2,
56+
r2: r2,
57+
foo3: foo3,
58+
r3: r3
2859
};
2960

3061
function withOpt$1(xOpt, y) {
@@ -45,30 +76,40 @@ var partial$1 = Curry._1((function (param) {
4576

4677
var total$1 = withOpt$1(10, 3)(4, 11);
4778

48-
function foo1(xOpt, y) {
79+
function foo1$1(xOpt, y) {
4980
var x = xOpt !== undefined ? xOpt : 3;
5081
return x + y | 0;
5182
}
5283

53-
var x = 3;
84+
var x$1 = 3;
5485

55-
var r1 = x + 11 | 0;
86+
var r1$1 = x$1 + 11 | 0;
5687

57-
function foo2(y, xOpt, zOpt) {
88+
function foo2$1(y, xOpt, zOpt) {
5889
var x = xOpt !== undefined ? xOpt : 3;
5990
var z = zOpt !== undefined ? zOpt : 4;
6091
return (x + y | 0) + z | 0;
6192
}
6293

63-
var r2 = foo2(11, undefined, undefined);
94+
var r2$1 = foo2$1(11, undefined, undefined);
95+
96+
function foo3$1(xOpt, yOpt) {
97+
var x = xOpt !== undefined ? xOpt : 3;
98+
var y = yOpt !== undefined ? yOpt : 4;
99+
return x + y | 0;
100+
}
101+
102+
var r3$1 = foo3$1(undefined, undefined);
64103

65104
exports.StandardNotation = StandardNotation;
66105
exports.withOpt = withOpt$1;
67106
exports.testWithOpt = testWithOpt$1;
68107
exports.partial = partial$1;
69108
exports.total = total$1;
70-
exports.foo1 = foo1;
71-
exports.r1 = r1;
72-
exports.foo2 = foo2;
73-
exports.r2 = r2;
109+
exports.foo1 = foo1$1;
110+
exports.r1 = r1$1;
111+
exports.foo2 = foo2$1;
112+
exports.r2 = r2$1;
113+
exports.foo3 = foo3$1;
114+
exports.r3 = r3$1;
74115
/* testWithOpt Not a pure module */

jscomp/test/uncurried_default.args.res

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,15 @@ module StandardNotation = {
33
let testWithOpt = withOpt(. 3)(. 4)
44
let partial = withOpt(~x=10)(3)(~z=4)(11)
55
let total = withOpt(. ~x=10, 3)(. ~z=4, 11)
6+
7+
let foo1 = (. ~x=3, ~y) => x+y
8+
let r1 = foo1(. ~y=11)
9+
10+
let foo2 = (. ~y, ~x=3, ~z=4) => x+y+z
11+
let r2 = foo2(. ~y=11)
12+
13+
let foo3 = (. ~x=3, ~y=4) => x+y
14+
let r3 = foo3(. )
615
}
716

817
@@uncurried
@@ -19,3 +28,6 @@ let r1 = foo1(~y=11)
1928

2029
let foo2 = (~y, ~x=3, ~z=4) => x+y+z
2130
let r2 = foo2(~y=11)
31+
32+
let foo3 = (~x=3, ~y=4) => x+y
33+
let r3 = foo3()

0 commit comments

Comments
 (0)