Skip to content

Commit dd4837d

Browse files
committed
Fix: Inline auto curried async functions produce invalid javascript
Port of PR #6010 to compiler version 10.1
1 parent bf4d21b commit dd4837d

7 files changed

+44
-13
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
- Fix issue with overlapping labelled argument with default value https://github.com/rescript-lang/syntax/pull/734
2828
- Fix issue with using alias and default value together https://github.com/rescript-lang/syntax/pull/734
2929
- Fix issue in `Js.Promise2` where `then` and `catch` were returning `undefined` https://github.com/rescript-lang/rescript-compiler/pull/5996
30+
- Fix issue in the compiler back-end where async functions passed to an `@uncurry` external would be inlined and transformed in a way that loses async https://github.com/rescript-lang/rescript-compiler/pull/6011
3031

3132
#### :rocket: New Feature
3233

jscomp/core/lam_eta_conversion.ml

+6-3
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,16 @@ let unsafe_adjust_to_arity loc ~(to_ : int) ?(from : int option) (fn : Lam.t) :
113113
let ap_info : Lam.ap_info =
114114
{ ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na }
115115
in
116+
let is_async_fn = match fn with
117+
| Lfunction { attr = {async}} -> async
118+
| _ -> false in
116119
match (from, fn) with
117120
| Some from, _ | None, Lfunction { arity = from } -> (
118-
if from = to_ then fn
121+
if from = to_ || is_async_fn then fn
119122
else if to_ = 0 then
120123
match fn with
121-
| Lfunction { params = [ param ]; body; attr = {async} } ->
122-
Lam.function_ ~arity:0 ~attr:{Lambda.default_function_attribute with async}
124+
| Lfunction { params = [ param ]; body } ->
125+
Lam.function_ ~arity:0 ~attr:Lambda.default_function_attribute
123126
~params:[]
124127
~body:(Lam.let_ Alias param Lam.unit body)
125128
(* could be only introduced by

jscomp/test/async_inline.js

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

33
var Curry = require("../../lib/js/curry.js");
4+
var React = require("react");
45

56
async function willBeInlined(param) {
67
return 3;
@@ -50,6 +51,12 @@ async function nested2(param) {
5051
};
5152
}
5253

54+
function onSubmit(param) {
55+
return React.useCallback(async function (_a, b) {
56+
return await b;
57+
});
58+
}
59+
5360
exports.willBeInlined = willBeInlined;
5461
exports.inlined = inlined;
5562
exports.wrapSomethingAsync = wrapSomethingAsync;
@@ -58,4 +65,5 @@ exports.M = M;
5865
exports.broken = broken$2;
5966
exports.nested1 = nested1;
6067
exports.nested2 = nested2;
68+
exports.onSubmit = onSubmit;
6169
/* inlined Not a pure module */

jscomp/test/async_inline.res

+11-1
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,14 @@ let broken = someAsyncFunction => broken(someAsyncFunction)
3939

4040
let nested1 = () => async (y) => await y
4141

42-
let nested2 = async () => async (y) => await y
42+
let nested2 = async () => async (y) => await y
43+
44+
type callback<'input, 'output> = 'input => 'output
45+
46+
@module("react")
47+
external useCallback: (@uncurry ('input => 'output)) => callback<'input, 'output> = "useCallback"
48+
49+
let onSubmit = () =>
50+
useCallback(async (_a, b) => {
51+
await b
52+
})

lib/4.06.1/unstable/js_compiler.ml

+6-3
Original file line numberDiff line numberDiff line change
@@ -98870,13 +98870,16 @@ let unsafe_adjust_to_arity loc ~(to_ : int) ?(from : int option) (fn : Lam.t) :
9887098870
let ap_info : Lam.ap_info =
9887198871
{ ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na }
9887298872
in
98873+
let is_async_fn = match fn with
98874+
| Lfunction { attr = {async}} -> async
98875+
| _ -> false in
9887398876
match (from, fn) with
9887498877
| Some from, _ | None, Lfunction { arity = from } -> (
98875-
if from = to_ then fn
98878+
if from = to_ || is_async_fn then fn
9887698879
else if to_ = 0 then
9887798880
match fn with
98878-
| Lfunction { params = [ param ]; body; attr = {async} } ->
98879-
Lam.function_ ~arity:0 ~attr:{Lambda.default_function_attribute with async}
98881+
| Lfunction { params = [ param ]; body } ->
98882+
Lam.function_ ~arity:0 ~attr:Lambda.default_function_attribute
9888098883
~params:[]
9888198884
~body:(Lam.let_ Alias param Lam.unit body)
9888298885
(* could be only introduced by

lib/4.06.1/unstable/js_playground_compiler.ml

+6-3
Original file line numberDiff line numberDiff line change
@@ -98870,13 +98870,16 @@ let unsafe_adjust_to_arity loc ~(to_ : int) ?(from : int option) (fn : Lam.t) :
9887098870
let ap_info : Lam.ap_info =
9887198871
{ ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na }
9887298872
in
98873+
let is_async_fn = match fn with
98874+
| Lfunction { attr = {async}} -> async
98875+
| _ -> false in
9887398876
match (from, fn) with
9887498877
| Some from, _ | None, Lfunction { arity = from } -> (
98875-
if from = to_ then fn
98878+
if from = to_ || is_async_fn then fn
9887698879
else if to_ = 0 then
9887798880
match fn with
98878-
| Lfunction { params = [ param ]; body; attr = {async} } ->
98879-
Lam.function_ ~arity:0 ~attr:{Lambda.default_function_attribute with async}
98881+
| Lfunction { params = [ param ]; body } ->
98882+
Lam.function_ ~arity:0 ~attr:Lambda.default_function_attribute
9888098883
~params:[]
9888198884
~body:(Lam.let_ Alias param Lam.unit body)
9888298885
(* could be only introduced by

lib/4.06.1/whole_compiler.ml

+6-3
Original file line numberDiff line numberDiff line change
@@ -268166,13 +268166,16 @@ let unsafe_adjust_to_arity loc ~(to_ : int) ?(from : int option) (fn : Lam.t) :
268166268166
let ap_info : Lam.ap_info =
268167268167
{ ap_loc = loc; ap_inlined = Default_inline; ap_status = App_na }
268168268168
in
268169+
let is_async_fn = match fn with
268170+
| Lfunction { attr = {async}} -> async
268171+
| _ -> false in
268169268172
match (from, fn) with
268170268173
| Some from, _ | None, Lfunction { arity = from } -> (
268171-
if from = to_ then fn
268174+
if from = to_ || is_async_fn then fn
268172268175
else if to_ = 0 then
268173268176
match fn with
268174-
| Lfunction { params = [ param ]; body; attr = {async} } ->
268175-
Lam.function_ ~arity:0 ~attr:{Lambda.default_function_attribute with async}
268177+
| Lfunction { params = [ param ]; body } ->
268178+
Lam.function_ ~arity:0 ~attr:Lambda.default_function_attribute
268176268179
~params:[]
268177268180
~body:(Lam.let_ Alias param Lam.unit body)
268178268181
(* could be only introduced by

0 commit comments

Comments
 (0)