Skip to content

Commit c32e8fe

Browse files
committed
Add a synthetic unit argument when all external parameters collapse to constants
1 parent b86e54d commit c32e8fe

File tree

3 files changed

+22
-4
lines changed

3 files changed

+22
-4
lines changed

compiler/frontend/ast_external_process.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -997,6 +997,24 @@ let handle_attributes (loc : Bs_loc.t) (type_annotation : Parsetree.core_type)
997997
new_arg_types,
998998
if arg_type = Ignore then i else i + 1 ))
999999
in
1000+
(* If every original argument was erased (e.g. all `@as(json ...) _`),
1001+
keep the external binding callable by threading a final `unit`
1002+
parameter through the type and arg specs. *)
1003+
let args, arg_type_specs =
1004+
match (args, arg_type_specs_length) with
1005+
| [], n when n > 0 ->
1006+
let unit_type =
1007+
Ast_helper.Typ.constr ~loc
1008+
(Location.mkloc (Longident.Lident "unit") loc)
1009+
[]
1010+
in
1011+
let unit_arg = {Parsetree.attrs = []; lbl = Nolabel; typ = unit_type} in
1012+
( [unit_arg],
1013+
arg_type_specs
1014+
@ [{External_arg_spec.arg_label = Arg_empty; arg_type = Extern_unit}]
1015+
)
1016+
| _ -> (args, arg_type_specs)
1017+
in
10001018
let ffi : External_ffi_types.external_spec =
10011019
external_desc_of_non_obj loc external_desc prim_name_with_source
10021020
arg_type_specs_length arg_types_ty arg_type_specs

tests/tests/src/AsInUncurriedExternals.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ function shouldNotFail(objectMode, name) {
1919
return 3;
2020
}
2121

22-
let constantValue = somescope.somefn({foo:true});
22+
let x = somescope.somefn({foo:true});
2323

2424
export {
2525
mo,
2626
options,
2727
shouldNotFail,
28-
constantValue,
28+
x,
2929
}
30-
/* constantValue Not a pure module */
30+
/* x Not a pure module */

tests/tests/src/AsInUncurriedExternals.res

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ let shouldNotFail: (~objectMode: _, ~name: string) => int = (~objectMode, ~name)
1717
@scope("somescope")
1818
external constantArgOnly: @as(json`{foo:true}`) _ => string = "somefn"
1919

20-
let constantValue = constantArgOnly
20+
let x = constantArgOnly()

0 commit comments

Comments
 (0)