Skip to content

Commit 9ad29cd

Browse files
committed
Fix issues with the arity of externals.
Fixes #6880
1 parent 101f90a commit 9ad29cd

15 files changed

+104
-24
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
- Allow free vars in types for type coercion `e :> t`. https://github.com/rescript-lang/rescript-compiler/pull/6828
2121
- Allow `private` in with constraints. https://github.com/rescript-lang/rescript-compiler/pull/6843
2222
- Add regex literals as syntax sugar for `@bs.re`. https://github.com/rescript-lang/rescript-compiler/pull/6776
23-
- Improved mechanism to determine arity of externals, which is consistent however the type is written. https://github.com/rescript-lang/rescript-compiler/pull/6874
23+
- Improved mechanism to determine arity of externals, which is consistent however the type is written. https://github.com/rescript-lang/rescript-compiler/pull/6874 https://github.com/rescript-lang/rescript-compiler/pull/6881
2424

2525
#### :boom: Breaking Change
2626

jscomp/core/lam_compile_external_call.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,9 @@ let translate_ffi (cxt : Lam_compile_context.t) arg_types
365365
2. support [@@scope "window"]
366366
we need know whether we should call [add_js_module] or not
367367
*)
368-
translate_scoped_module_val external_module_name name scopes ~dynamic_import
368+
let e = translate_scoped_module_val external_module_name name scopes ~dynamic_import in
369+
if args = [] then e
370+
else E.call ~info:{ arity = Full; call_info = Call_na } e args
369371
| Js_module_as_class module_name ->
370372
let fn = external_var module_name ~dynamic_import in
371373
let args, eff = assemble_args_no_splice arg_types args in

jscomp/frontend/external_ffi_types.ml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,13 @@ let from_string s : t =
240240

241241
let () =
242242
Primitive.coerce :=
243-
fun ({prim_name; prim_arity; prim_native_name; prim_alloc = _} :
243+
fun ({
244+
prim_name;
245+
prim_arity;
246+
prim_native_name;
247+
prim_alloc = _;
248+
prim_from_constructor = _;
249+
} :
244250
Primitive.description) (p2 : Primitive.description) ->
245251
let p2_native = p2.prim_native_name in
246252
prim_name = p2.prim_name && prim_arity = p2.prim_arity

jscomp/gentype_tests/typescript-react-example/src/ImportHookDefault.res.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/gentype_tests/typescript-react-example/src/ImportHooks.res.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/gentype_tests/typescript-react-example/src/ImportIndex.res.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/gentype_tests/typescript-react-example/src/JSXV4.res.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/gentype_tests/typescript-react-example/src/MyInput.res.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/ml/primitive.ml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type description =
2525
prim_arity: int; (* Number of arguments *)
2626
prim_alloc: bool; (* Does it allocates or raise? *)
2727
prim_native_name: string; (* Name of C function for the nat. code gen. *)
28+
prim_from_constructor: bool; (* Is it from a type constructor instead of a concrete function type? *)
2829
}
2930

3031
let coerce : (description -> description -> bool) ref =
@@ -37,15 +38,17 @@ let simple ~name ~arity ~alloc =
3738
{prim_name = name;
3839
prim_arity = arity;
3940
prim_alloc = alloc;
40-
prim_native_name = "";}
41+
prim_native_name = "";
42+
prim_from_constructor = false;}
4143

4244
let make ~name ~alloc ~native_name ~arity =
4345
{prim_name = name;
4446
prim_arity = arity;
4547
prim_alloc = alloc;
46-
prim_native_name = native_name;}
48+
prim_native_name = native_name;
49+
prim_from_constructor = false;}
4750

48-
let parse_declaration valdecl ~arity =
51+
let parse_declaration valdecl ~arity ~from_constructor =
4952
let name, native_name =
5053
match valdecl.pval_prim with
5154
| name :: name2 :: _ -> (name, name2)
@@ -56,7 +59,8 @@ let parse_declaration valdecl ~arity =
5659
{prim_name = name;
5760
prim_arity = arity;
5861
prim_alloc = true;
59-
prim_native_name = native_name;}
62+
prim_native_name = native_name;
63+
prim_from_constructor = from_constructor}
6064

6165
open Outcometree
6266

jscomp/ml/primitive.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type description = private
2222
prim_arity: int; (* Number of arguments *)
2323
prim_alloc: bool; (* Does it allocates or raise? *)
2424
prim_native_name: string; (* Name of C function for the nat. code gen. *)
25+
prim_from_constructor: bool; (* Is it from a type constructor instead of a concrete function type? *)
2526
}
2627

2728
(* Invariant [List.length d.prim_native_repr_args = d.prim_arity] *)
@@ -42,6 +43,7 @@ val make
4243
val parse_declaration
4344
: Parsetree.value_description
4445
-> arity: int
46+
-> from_constructor: bool
4547
-> description
4648

4749
val print

jscomp/ml/translcore.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ let transl_primitive loc p env ty =
496496
:: make_params (n - 1) total
497497
in
498498
let prim_arity = p.prim_arity in
499-
if prim_arity = 0 then Lprim (prim, [], loc)
499+
if p.prim_from_constructor || prim_arity = 0 then Lprim (prim, [], loc)
500500
else
501501
let params =
502502
if prim_arity = 1 then [ Ident.create "prim" ]

jscomp/ml/typedecl.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,8 +1718,10 @@ let rec arity_from_arrow_type env core_type ty =
17181718

17191719
let parse_arity env core_type ty =
17201720
match Ast_uncurried.uncurried_type_get_arity_opt ~env ty with
1721-
| Some arity -> arity
1722-
| None -> arity_from_arrow_type env core_type ty
1721+
| Some arity ->
1722+
let from_constructor = Ast_uncurried.uncurried_type_get_arity_opt ~env:Env.empty ty = None in
1723+
(arity, from_constructor)
1724+
| None -> (arity_from_arrow_type env core_type ty, false)
17231725

17241726
(* Translate a value declaration *)
17251727
let transl_value_decl env loc valdecl =
@@ -1733,7 +1735,7 @@ let transl_value_decl env loc valdecl =
17331735
| [] ->
17341736
raise (Error(valdecl.pval_loc, Val_in_structure))
17351737
| _ ->
1736-
let arity =
1738+
let arity, from_constructor =
17371739
let rec scan_attributes (attrs : Parsetree.attributes) =
17381740
match attrs with
17391741
| ({txt = "internal.arity";_}, (* This is likely not needed in uncurried mode *)
@@ -1747,9 +1749,9 @@ let transl_value_decl env loc valdecl =
17471749
in
17481750
match scan_attributes valdecl.pval_attributes with
17491751
| None -> parse_arity env valdecl.pval_type ty
1750-
| Some x -> x
1752+
| Some x -> x, false
17511753
in
1752-
let prim = Primitive.parse_declaration valdecl ~arity in
1754+
let prim = Primitive.parse_declaration valdecl ~arity ~from_constructor in
17531755
let prim_native_name = prim.prim_native_name in
17541756
if prim.prim_arity = 0 &&
17551757
not ( String.length prim_native_name >= 20 &&

jscomp/test/ExternalArity.js

Lines changed: 32 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

jscomp/test/ExternalArity.res

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,42 @@
11
@@uncurried
22

3+
@@config({
4+
flags: ["-bs-jsx", "4"],
5+
})
6+
37
type u = (int, int) => int
48
@val external v1: u = "v" // arity from u is implicit
59
@val external v2: (int, int) => int = "v" // arity is explicit
610

7-
let f1 = x => v1(x,x)
8-
let f2 = x => v2(x,x)
11+
let f1 = x => v1(x, x)
12+
let f2 = x => v2(x, x)
13+
14+
module FromTypeConstructor = {
15+
type fn<'props, 'return> = 'props => 'return
16+
17+
external foo1: fn<int, int> = "foo1"
18+
let test1 = foo1(10)
19+
20+
external foo2: int => int = "foo2"
21+
let test2 = foo2(20)
22+
23+
external foo3: (~x: int=?, ~y: int) => int = "foo3"
24+
let test3 = foo3(~y=3)
25+
}
26+
27+
module ReactTest = {
28+
module React = {
29+
type element = Jsx.element
30+
type componentLike<'props, 'return> = 'props => 'return
31+
type component<'props> = Jsx.component<'props>
32+
33+
@module("react/jsx-runtime")
34+
external jsx: (component<'props>, 'props) => element = "jsx"
35+
}
36+
37+
module FormattedMessage = {
38+
@react.component @module("react-intl")
39+
external make: (~id: string, ~defaultMessage: string) => React.element = "FormattedMessage"
40+
}
41+
let _ = <FormattedMessage id="test" defaultMessage="Test" />
42+
}

jscomp/test/bs_splice_partial.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)