Skip to content

Commit bbf4fbc

Browse files
authored
Special case uncurried fun with 1 arg of unit type (#6131)
* Specia case uncurried fun with 1 arg of unit type * Update artifacts.txt * v2 * back * back * Update artifacts.txt * simplify * Seems to work with minimal changes. * Update artifacts.txt * Pass the information oneUnitArg lower down the compiler stack. Instead of removing the arguments on the lambda layer, pass the information down via the lambda layer using the additional field oneUnitArg. When this reaches the Lam layer with ocaml_fun in Lam_compile, only then remove the param. This ensures the code emitted is the same, except for the parameter. * Update CHANGELOG.md
1 parent 503a54b commit bbf4fbc

33 files changed

+74
-41
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
1313
# 11.0.0-alpha.2 (Unreleased)
1414

15+
#### :bug: Bug Fix
16+
- Special case generation of uncurried functions with 1 argument of unit type so they don't take a parameter. https://github.com/rescript-lang/rescript-compiler/pull/6131
17+
1518
## :rocket: Main New Features
1619

1720
- Add support for type coercion `:>` for records. https://github.com/rescript-lang/rescript-compiler/pull/5721

jscomp/core/js_exp_make.ml

+2-1
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ let unit : t = { expression_desc = Undefined; comment = None }
204204
[Js_fun_env.empty] is a mutable state ..
205205
*)
206206

207-
let ocaml_fun ?comment ?immutable_mask ~return_unit ~async params body : t =
207+
let ocaml_fun ?comment ?immutable_mask ~return_unit ~async ~oneUnitArg params body : t =
208+
let params = if oneUnitArg then [] else params in
208209
let len = List.length params in
209210
{
210211
expression_desc =

jscomp/core/js_exp_make.mli

+1
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ val ocaml_fun :
8989
?immutable_mask:bool array ->
9090
return_unit:bool ->
9191
async:bool ->
92+
oneUnitArg:bool ->
9293
J.ident list ->
9394
J.block ->
9495
t

jscomp/core/lam.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ let rec is_eta_conversion_exn params inner_args outer_args : t list =
273273
| x :: xs, Lvar y :: ys, r :: rest when Ident.same x y ->
274274
r :: is_eta_conversion_exn xs ys rest
275275
| ( x :: xs,
276-
Lprim ({ primitive = Pjs_fn_make _; args = [ Lvar y ] } as p) :: ys,
276+
Lprim ({ primitive = Pjs_fn_make _ | Pjs_fn_make_unit; args = [ Lvar y ] } as p) :: ys,
277277
r :: rest )
278278
when Ident.same x y ->
279279
Lprim { p with args = [ r ] } :: is_eta_conversion_exn xs ys rest

jscomp/core/lam_analysis.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ let rec no_side_effects (lam : Lam.t) : bool =
5959
| _ -> false)
6060
| Pcreate_extension _ | Pjs_typeof | Pis_null | Pis_not_none | Psome
6161
| Psome_not_nest | Pis_undefined | Pis_null_undefined | Pnull_to_opt
62-
| Pundefined_to_opt | Pnull_undefined_to_opt | Pjs_fn_make _
62+
| Pundefined_to_opt | Pnull_undefined_to_opt | Pjs_fn_make _ | Pjs_fn_make_unit
6363
| Pjs_object_create _
6464
(* TODO: check *)
6565
| Pbytes_to_string | Pmakeblock _

jscomp/core/lam_compile.ml

+9-6
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ let rec apply_with_arity_aux (fn : J.expression) (arity : int list)
5555
let params =
5656
Ext_list.init (x - len) (fun _ -> Ext_ident.create "param")
5757
in
58-
E.ocaml_fun params ~return_unit:false (* unknown info *) ~async:false
58+
E.ocaml_fun params ~return_unit:false (* unknown info *) ~async:false ~oneUnitArg:false
5959
[
6060
S.return_stmt
6161
(E.call
@@ -315,7 +315,7 @@ and compile_external_field_apply (appinfo : Lam.apply) (module_id : Ident.t)
315315
and compile_recursive_let ~all_bindings (cxt : Lam_compile_context.t)
316316
(id : Ident.t) (arg : Lam.t) : Js_output.t * initialization =
317317
match arg with
318-
| Lfunction { params; body; attr = { return_unit; async } } ->
318+
| Lfunction { params; body; attr = { return_unit; async; oneUnitArg } } ->
319319
let continue_label = Lam_util.generate_label ~name:id.name () in
320320
(* TODO: Think about recursive value
321321
{[
@@ -355,7 +355,7 @@ and compile_recursive_let ~all_bindings (cxt : Lam_compile_context.t)
355355
it will be renamed into [method]
356356
when it is detected by a primitive
357357
*)
358-
~return_unit ~async ~immutable_mask:ret.immutable_mask
358+
~return_unit ~async ~oneUnitArg ~immutable_mask:ret.immutable_mask
359359
(Ext_list.map params (fun x ->
360360
Map_ident.find_default ret.new_params x x))
361361
[
@@ -366,7 +366,7 @@ and compile_recursive_let ~all_bindings (cxt : Lam_compile_context.t)
366366
]
367367
else
368368
(* TODO: save computation of length several times *)
369-
E.ocaml_fun params (Js_output.output_as_block output) ~return_unit ~async
369+
E.ocaml_fun params (Js_output.output_as_block output) ~return_unit ~async ~oneUnitArg
370370
in
371371
( Js_output.output_of_expression
372372
(Declare (Alias, id))
@@ -1458,6 +1458,7 @@ and compile_apply (appinfo : Lam.apply) (lambda_cxt : Lam_compile_context.t) =
14581458
*)
14591459
(* TODO: use [fold]*)
14601460
let _, assigned_params, new_params =
1461+
let args = if ret.params = [] then [] else args in
14611462
Ext_list.fold_left2 ret.params args (0, [], Map_ident.empty)
14621463
(fun param arg (i, assigns, new_params) ->
14631464
match arg with
@@ -1628,6 +1629,8 @@ and compile_prim (prim_info : Lam.prim_info)
16281629
| { primitive = Pjs_fn_make arity; args = [ fn ]; loc } ->
16291630
compile_lambda lambda_cxt
16301631
(Lam_eta_conversion.unsafe_adjust_to_arity loc ~to_:arity ?from:None fn)
1632+
| { primitive = Pjs_fn_make_unit; args = [ fn ]; loc } ->
1633+
compile_lambda lambda_cxt fn
16311634
| { primitive = Pjs_fn_make _; args = [] | _ :: _ :: _ } -> assert false
16321635
| { primitive = Pjs_object_create labels; args } ->
16331636
let args_block, args_expr =
@@ -1666,10 +1669,10 @@ and compile_prim (prim_info : Lam.prim_info)
16661669
and compile_lambda (lambda_cxt : Lam_compile_context.t) (cur_lam : Lam.t) :
16671670
Js_output.t =
16681671
match cur_lam with
1669-
| Lfunction { params; body; attr = { return_unit; async } } ->
1672+
| Lfunction { params; body; attr = { return_unit; async; oneUnitArg } } ->
16701673
Js_output.output_of_expression lambda_cxt.continuation
16711674
~no_effects:no_effects_const
1672-
(E.ocaml_fun params ~return_unit ~async
1675+
(E.ocaml_fun params ~return_unit ~async ~oneUnitArg
16731676
(* Invariant: jmp_table can not across function boundary,
16741677
here we share env
16751678
*)

jscomp/core/lam_compile_primitive.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ let translate loc (cxt : Lam_compile_context.t) (prim : Lam_primitive.t)
8484
| Pis_undefined -> E.is_undef (Ext_list.singleton_exn args)
8585
| Pis_null_undefined -> E.is_null_undefined (Ext_list.singleton_exn args)
8686
| Pjs_typeof -> E.typeof (Ext_list.singleton_exn args)
87-
| Pjs_unsafe_downgrade _ | Pdebugger | Pvoid_run | Pfull_apply | Pjs_fn_make _
87+
| Pjs_unsafe_downgrade _ | Pdebugger | Pvoid_run | Pfull_apply | Pjs_fn_make _ | Pjs_fn_make_unit
8888
->
8989
assert false (* already handled by {!Lam_compile} *)
9090
| Pjs_fn_method -> assert false

jscomp/core/lam_convert.ml

+2
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,8 @@ let convert (exports : Set_ident.t) (lam : Lambda.lambda) :
493493
| "#run" -> Pvoid_run
494494
| "#fn_mk" ->
495495
Pjs_fn_make (Ext_pervasives.nat_of_string_exn p.prim_native_name)
496+
| "#fn_mk_unit" ->
497+
Pjs_fn_make_unit
496498
| "#fn_method" -> Pjs_fn_method
497499
| "#unsafe_downgrade" ->
498500
Pjs_unsafe_downgrade { name = Ext_string.empty; setter = false }

jscomp/core/lam_pass_alpha_conversion.ml

+6
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ let alpha_conversion (meta : Lam_stats.t) (lam : Lam.t) : Lam.t =
6969
let arg = simpl arg in
7070
Lam_eta_conversion.unsafe_adjust_to_arity loc ~to_:len ~from:x arg
7171
| None -> Lam.prim ~primitive ~args:[ simpl arg ] loc)
72+
| Lprim { primitive = Pjs_fn_make_unit; args = [ arg ]; loc } ->
73+
let arg = match arg with
74+
| Lfunction ({arity=1; params=[x]; attr; body}) ->
75+
Lam.function_ ~params:[x] ~attr:{attr with oneUnitArg=true} ~body ~arity:1
76+
| _ -> arg in
77+
simpl arg
7278
| Lprim { primitive; args; loc } ->
7379
Lam.prim ~primitive ~args:(Ext_list.map args simpl) loc
7480
| Lfunction { arity; params; body; attr } ->

jscomp/core/lam_primitive.ml

+2
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ type t =
129129
| Pupdate_mod
130130
| Praw_js_code of Js_raw_info.t
131131
| Pjs_fn_make of int
132+
| Pjs_fn_make_unit
132133
| Pvoid_run
133134
| Pfull_apply
134135
(* we wrap it when do the conversion to prevent
@@ -307,6 +308,7 @@ let eq_primitive_approx (lhs : t) (rhs : t) =
307308
| Pjs_unsafe_downgrade rhs -> name = rhs.name && setter = rhs.setter
308309
| _ -> false)
309310
| Pjs_fn_make i -> ( match rhs with Pjs_fn_make i1 -> i = i1 | _ -> false)
311+
| Pjs_fn_make_unit -> rhs = Pjs_fn_make_unit
310312
| Pvoid_run -> rhs = Pvoid_run
311313
| Pfull_apply -> rhs = Pfull_apply
312314
| Pjs_fn_method -> rhs = Pjs_fn_method

jscomp/core/lam_primitive.mli

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ type t =
121121
| Pupdate_mod
122122
| Praw_js_code of Js_raw_info.t
123123
| Pjs_fn_make of int
124+
| Pjs_fn_make_unit
124125
| Pvoid_run
125126
| Pfull_apply
126127
| Pjs_fn_method

jscomp/core/lam_print.ml

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ let primitive ppf (prim : Lam_primitive.t) =
6363
| Pvoid_run -> fprintf ppf "#run"
6464
| Pfull_apply -> fprintf ppf "#full_apply"
6565
| Pjs_fn_make i -> fprintf ppf "js_fn_make_%i" i
66+
| Pjs_fn_make_unit -> fprintf ppf "js_fn_make_unit"
6667
| Pjs_fn_method -> fprintf ppf "js_fn_method"
6768
| Pdebugger -> fprintf ppf "debugger"
6869
| Praw_js_code _ -> fprintf ppf "[raw]"

jscomp/ml/lambda.ml

+4-1
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ type function_attribute = {
270270
stub: bool;
271271
return_unit : bool;
272272
async : bool;
273+
oneUnitArg : bool;
273274
}
274275

275276
type lambda =
@@ -298,7 +299,8 @@ and lfunction =
298299
params: Ident.t list;
299300
body: lambda;
300301
attr: function_attribute; (* specified with [@inline] attribute *)
301-
loc: Location.t; }
302+
loc: Location.t;
303+
}
302304

303305
and lambda_apply =
304306
{ ap_func : lambda;
@@ -338,6 +340,7 @@ let default_function_attribute = {
338340
stub = false;
339341
return_unit = false;
340342
async = false;
343+
oneUnitArg = false;
341344
}
342345

343346
let default_stub_attribute =

jscomp/ml/lambda.mli

+1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ type function_attribute = {
271271
stub: bool;
272272
return_unit : bool;
273273
async : bool;
274+
oneUnitArg : bool;
274275
}
275276

276277
type lambda =

jscomp/ml/translcore.ml

+10-2
Original file line numberDiff line numberDiff line change
@@ -781,9 +781,17 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
781781
(* ReScript uncurried encoding *)
782782
let loc = expr.exp_loc in
783783
let lambda = transl_exp expr in
784-
let arity_s = Ast_uncurried.uncurried_type_get_arity ~env:e.exp_env e.exp_type |> string_of_int in
784+
let arity = Ast_uncurried.uncurried_type_get_arity ~env:e.exp_env e.exp_type in
785+
let arity_s = arity |> string_of_int in
786+
let name = match (Ctype.expand_head expr.exp_env expr.exp_type).desc with
787+
| Tarrow (Nolabel, t, _, _) -> (
788+
match (Ctype.expand_head expr.exp_env t).desc with
789+
| Tconstr (Pident {name= "unit"}, [], _) -> "#fn_mk_unit"
790+
| _ -> "#fn_mk"
791+
)
792+
| _ -> "#fn_mk" in
785793
let prim =
786-
Primitive.make ~name:"#fn_mk" ~alloc:true ~native_name:arity_s
794+
Primitive.make ~name ~alloc:true ~native_name:arity_s
787795
~native_repr_args:[ Same_as_ocaml_repr ]
788796
~native_repr_res:Same_as_ocaml_repr
789797
in

jscomp/ml/translmod.ml

+1
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ let rec compile_functor mexp coercion root_path loc =
277277
stub = false;
278278
return_unit = false;
279279
async = false;
280+
oneUnitArg = false;
280281
};
281282
loc;
282283
body;

jscomp/test/UncurriedExternals.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ function tsiU$1(c) {
123123
});
124124
}
125125

126-
var match$1 = React.useState(function (param) {
126+
var match$1 = React.useState(function () {
127127
return 3;
128128
});
129129

jscomp/test/async_await.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function next(n) {
66
return n + 1 | 0;
77
}
88

9-
async function useNext(param) {
9+
async function useNext() {
1010
return 4;
1111
}
1212

@@ -19,7 +19,7 @@ function Make(I) {
1919
};
2020
}
2121

22-
async function topFoo(param) {
22+
async function topFoo() {
2323
return 1;
2424
}
2525

jscomp/test/event_ffi.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ function ocaml_run(b, c) {
3838
return (x + b | 0) + c | 0;
3939
}
4040

41-
function a0(param) {
41+
function a0() {
4242
console.log("hi");
4343
}
4444

jscomp/test/ffi_arity_test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ var hh = [
3939
return parseInt(x);
4040
});
4141

42-
function u(param) {
42+
function u() {
4343
return 3;
4444
}
4545

@@ -53,7 +53,7 @@ function fff(param) {
5353
vvv.contents = vvv.contents + 1 | 0;
5454
}
5555

56-
function g(param) {
56+
function g() {
5757
fff(undefined);
5858
}
5959

jscomp/test/mt.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ function old_from_promise_suites_donotuse(name, suites) {
230230
var match = $$Array.to_list(Process.argv);
231231
if (match) {
232232
if (is_mocha(undefined)) {
233-
describe(name, (function (param) {
233+
describe(name, (function () {
234234
List.iter((function (param) {
235235
var code = param[1];
236236
it(param[0], (function (param) {

jscomp/test/pipe_send_readline.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
function u(rl) {
55
return rl.on("line", (function (x) {
66
console.log(x);
7-
})).on("close", (function (param) {
7+
})).on("close", (function () {
88
console.log("finished");
99
}));
1010
}

jscomp/test/ppx_apply_test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function eq(loc, x, y) {
2929

3030
var u = 3;
3131

32-
function nullary(param) {
32+
function nullary() {
3333
return 3;
3434
}
3535

jscomp/test/raw_output_test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function mk(fn) {
88

99
(((_)=> console.log('should works'))(undefined));
1010

11-
console.log((function (param) {
11+
console.log((function () {
1212
return 1;
1313
})(undefined));
1414

jscomp/test/reactTestUtils.js

+2-2
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 (param) {
10+
var reactFunc = function () {
1111
Curry._1(func, undefined);
1212
};
1313
TestUtils.act(reactFunc);
1414
}
1515

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

jscomp/test/tramp_fib.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function fib(n, k) {
2020
} else {
2121
return {
2222
TAG: "Suspend",
23-
_0: (function (param) {
23+
_0: (function () {
2424
return fib(n - 1 | 0, (function (v0) {
2525
return fib(n - 2 | 0, (function (v1) {
2626
return k(v0 + v1 | 0);
@@ -54,7 +54,7 @@ function isEven(n) {
5454
if (n !== 1) {
5555
return {
5656
TAG: "Suspend",
57-
_0: (function (param) {
57+
_0: (function () {
5858
return isOdd(n - 1 | 0);
5959
})
6060
};

jscomp/test/uncurried_cast.js

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

79-
function testRaise$1(param) {
79+
function testRaise$1() {
8080
throw {
8181
RE_EXN_ID: E,
8282
Error: new Error()

jscomp/test/uncurry_glob_test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function M(U) {
88
};
99
}
1010

11-
function f(param) {
11+
function f() {
1212
return 3;
1313
}
1414

jscomp/test/uncurry_test.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22

33

4-
function f0(param) {
4+
function f0() {
55
return 0;
66
}
77

@@ -25,7 +25,7 @@ console.log([
2525
1
2626
]);
2727

28-
function xx(_param) {
28+
function xx() {
2929
while(true) {
3030
_param = undefined;
3131
continue ;

0 commit comments

Comments
 (0)