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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 9 additions & 6 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

0 commit comments

Comments
 (0)