Skip to content

Commit bd8854d

Browse files
committed
Fix compiler ppx issue when combining async and uncurried application
Fixes #5854 The compiler ppx for `async` and `await` was propagating annotations of the body. When the body happens to be an uncurried application, the `@res.app` annotation was propagated to the code generated by the PPX and produced a type error (E.g. it would generate an uncurried call to the internal function `unsafe_await`).
1 parent b26bede commit bd8854d

File tree

9 files changed

+83
-49
lines changed

9 files changed

+83
-49
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ These are only breaking changes for unformatted code.
4343
- Fix issue in printing uncurried callbacks https://github.com/rescript-lang/rescript-compiler/pull/5828
4444
- Fix formatting uncurried functions with attributes https://github.com/rescript-lang/rescript-compiler/pull/5829
4545
- Fix parsing/printing uncurried functions with type parameters https://github.com/rescript-lang/rescript-compiler/pull/5849
46+
- Fix compiler ppx issue when combining `async` and uncurried application https://github.com/rescript-lang/rescript-compiler/pull/5856
4647

4748
#### :nail_care: Polish
4849

jscomp/frontend/ast_async.ml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
let add_promise_type ~async (result : Parsetree.expression) =
22
if async then
3-
let txt =
4-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async")
3+
let loc = result.pexp_loc in
4+
let unsafe_async =
5+
Ast_helper.Exp.ident ~loc
6+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_async"); loc }
57
in
6-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = result.pexp_loc } in
7-
{
8-
result with
9-
pexp_desc = Pexp_apply ({ result with pexp_desc }, [ (Nolabel, result) ]);
10-
}
8+
Ast_helper.Exp.apply ~loc unsafe_async [ (Nolabel, result) ]
119
else result
1210

1311
let add_async_attribute ~async (body : Parsetree.expression) =
@@ -30,6 +28,6 @@ let rec add_promise_to_result (e : Parsetree.expression) =
3028
let make_function_async ~async (e : Parsetree.expression) =
3129
if async then
3230
match e.pexp_desc with
33-
| Pexp_fun _ -> add_async_attribute ~async (add_promise_to_result e)
31+
| Pexp_fun _ -> add_promise_to_result e
3432
| _ -> assert false
3533
else e

jscomp/frontend/ast_await.ml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
let create_await_expression (e : Parsetree.expression) =
2-
let txt =
3-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await")
2+
let loc = e.pexp_loc in
3+
let unsafe_await =
4+
Ast_helper.Exp.ident ~loc
5+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_await"); loc }
46
in
5-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
6-
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
7+
Ast_helper.Exp.apply ~loc unsafe_await [ (Nolabel, e) ]

jscomp/test/async_await.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
4+
function next(n) {
5+
return n + 1 | 0;
6+
}
7+
8+
async function useNext(param) {
9+
return 4;
10+
}
11+
12+
function Make(I) {
13+
var get = async function (key) {
14+
return await I.get(key);
15+
};
16+
return {
17+
get: get
18+
};
19+
}
20+
21+
exports.next = next;
22+
exports.useNext = useNext;
23+
exports.Make = Make;
24+
/* No side effect */

jscomp/test/async_await.res

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@@uncurried
2+
3+
let next = n => n + 1
4+
let useNext = async () => next(3)
5+
6+
module type Impl = {
7+
let get: string => Js.Promise.t<string>
8+
}
9+
10+
module Make = (I: Impl) => {
11+
let get = async key => await I.get(key)
12+
}

jscomp/test/build.ninja

Lines changed: 2 additions & 1 deletion
Large diffs are not rendered by default.

lib/4.06.1/unstable/js_compiler.ml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145143,14 +145143,12 @@ module Ast_async
145143145143
#1 "ast_async.ml"
145144145144
let add_promise_type ~async (result : Parsetree.expression) =
145145145145
if async then
145146-
let txt =
145147-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async")
145146+
let loc = result.pexp_loc in
145147+
let unsafe_async =
145148+
Ast_helper.Exp.ident ~loc
145149+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_async"); loc }
145148145150
in
145149-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = result.pexp_loc } in
145150-
{
145151-
result with
145152-
pexp_desc = Pexp_apply ({ result with pexp_desc }, [ (Nolabel, result) ]);
145153-
}
145151+
Ast_helper.Exp.apply ~loc unsafe_async [ (Nolabel, result) ]
145154145152
else result
145155145153

145156145154
let add_async_attribute ~async (body : Parsetree.expression) =
@@ -145173,7 +145171,7 @@ let rec add_promise_to_result (e : Parsetree.expression) =
145173145171
let make_function_async ~async (e : Parsetree.expression) =
145174145172
if async then
145175145173
match e.pexp_desc with
145176-
| Pexp_fun _ -> add_async_attribute ~async (add_promise_to_result e)
145174+
| Pexp_fun _ -> add_promise_to_result e
145177145175
| _ -> assert false
145178145176
else e
145179145177

@@ -145664,11 +145662,12 @@ module Ast_await
145664145662
= struct
145665145663
#1 "ast_await.ml"
145666145664
let create_await_expression (e : Parsetree.expression) =
145667-
let txt =
145668-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await")
145665+
let loc = e.pexp_loc in
145666+
let unsafe_await =
145667+
Ast_helper.Exp.ident ~loc
145668+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_await"); loc }
145669145669
in
145670-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
145671-
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
145670+
Ast_helper.Exp.apply ~loc unsafe_await [ (Nolabel, e) ]
145672145671

145673145672
end
145674145673
module Bs_ast_mapper : sig

lib/4.06.1/unstable/js_playground_compiler.ml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145143,14 +145143,12 @@ module Ast_async
145143145143
#1 "ast_async.ml"
145144145144
let add_promise_type ~async (result : Parsetree.expression) =
145145145145
if async then
145146-
let txt =
145147-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async")
145146+
let loc = result.pexp_loc in
145147+
let unsafe_async =
145148+
Ast_helper.Exp.ident ~loc
145149+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_async"); loc }
145148145150
in
145149-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = result.pexp_loc } in
145150-
{
145151-
result with
145152-
pexp_desc = Pexp_apply ({ result with pexp_desc }, [ (Nolabel, result) ]);
145153-
}
145151+
Ast_helper.Exp.apply ~loc unsafe_async [ (Nolabel, result) ]
145154145152
else result
145155145153

145156145154
let add_async_attribute ~async (body : Parsetree.expression) =
@@ -145173,7 +145171,7 @@ let rec add_promise_to_result (e : Parsetree.expression) =
145173145171
let make_function_async ~async (e : Parsetree.expression) =
145174145172
if async then
145175145173
match e.pexp_desc with
145176-
| Pexp_fun _ -> add_async_attribute ~async (add_promise_to_result e)
145174+
| Pexp_fun _ -> add_promise_to_result e
145177145175
| _ -> assert false
145178145176
else e
145179145177

@@ -145664,11 +145662,12 @@ module Ast_await
145664145662
= struct
145665145663
#1 "ast_await.ml"
145666145664
let create_await_expression (e : Parsetree.expression) =
145667-
let txt =
145668-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await")
145665+
let loc = e.pexp_loc in
145666+
let unsafe_await =
145667+
Ast_helper.Exp.ident ~loc
145668+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_await"); loc }
145669145669
in
145670-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
145671-
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
145670+
Ast_helper.Exp.apply ~loc unsafe_await [ (Nolabel, e) ]
145672145671

145673145672
end
145674145673
module Bs_ast_mapper : sig

lib/4.06.1/whole_compiler.ml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -155427,14 +155427,12 @@ module Ast_async
155427155427
#1 "ast_async.ml"
155428155428
let add_promise_type ~async (result : Parsetree.expression) =
155429155429
if async then
155430-
let txt =
155431-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async")
155430+
let loc = result.pexp_loc in
155431+
let unsafe_async =
155432+
Ast_helper.Exp.ident ~loc
155433+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_async"); loc }
155432155434
in
155433-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = result.pexp_loc } in
155434-
{
155435-
result with
155436-
pexp_desc = Pexp_apply ({ result with pexp_desc }, [ (Nolabel, result) ]);
155437-
}
155435+
Ast_helper.Exp.apply ~loc unsafe_async [ (Nolabel, result) ]
155438155436
else result
155439155437

155440155438
let add_async_attribute ~async (body : Parsetree.expression) =
@@ -155457,7 +155455,7 @@ let rec add_promise_to_result (e : Parsetree.expression) =
155457155455
let make_function_async ~async (e : Parsetree.expression) =
155458155456
if async then
155459155457
match e.pexp_desc with
155460-
| Pexp_fun _ -> add_async_attribute ~async (add_promise_to_result e)
155458+
| Pexp_fun _ -> add_promise_to_result e
155461155459
| _ -> assert false
155462155460
else e
155463155461

@@ -155948,11 +155946,12 @@ module Ast_await
155948155946
= struct
155949155947
#1 "ast_await.ml"
155950155948
let create_await_expression (e : Parsetree.expression) =
155951-
let txt =
155952-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await")
155949+
let loc = e.pexp_loc in
155950+
let unsafe_await =
155951+
Ast_helper.Exp.ident ~loc
155952+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_await"); loc }
155953155953
in
155954-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
155955-
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
155954+
Ast_helper.Exp.apply ~loc unsafe_await [ (Nolabel, e) ]
155956155955

155957155956
end
155958155957
module Bs_ast_mapper : sig

0 commit comments

Comments
 (0)