Skip to content

Commit f99baad

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 4e95019 commit f99baad

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
@@ -145137,14 +145137,12 @@ module Ast_async
145137145137
#1 "ast_async.ml"
145138145138
let add_promise_type ~async (result : Parsetree.expression) =
145139145139
if async then
145140-
let txt =
145141-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async")
145140+
let loc = result.pexp_loc in
145141+
let unsafe_async =
145142+
Ast_helper.Exp.ident ~loc
145143+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_async"); loc }
145142145144
in
145143-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = result.pexp_loc } in
145144-
{
145145-
result with
145146-
pexp_desc = Pexp_apply ({ result with pexp_desc }, [ (Nolabel, result) ]);
145147-
}
145145+
Ast_helper.Exp.apply ~loc unsafe_async [ (Nolabel, result) ]
145148145146
else result
145149145147

145150145148
let add_async_attribute ~async (body : Parsetree.expression) =
@@ -145167,7 +145165,7 @@ let rec add_promise_to_result (e : Parsetree.expression) =
145167145165
let make_function_async ~async (e : Parsetree.expression) =
145168145166
if async then
145169145167
match e.pexp_desc with
145170-
| Pexp_fun _ -> add_async_attribute ~async (add_promise_to_result e)
145168+
| Pexp_fun _ -> add_promise_to_result e
145171145169
| _ -> assert false
145172145170
else e
145173145171

@@ -145658,11 +145656,12 @@ module Ast_await
145658145656
= struct
145659145657
#1 "ast_await.ml"
145660145658
let create_await_expression (e : Parsetree.expression) =
145661-
let txt =
145662-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await")
145659+
let loc = e.pexp_loc in
145660+
let unsafe_await =
145661+
Ast_helper.Exp.ident ~loc
145662+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_await"); loc }
145663145663
in
145664-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
145665-
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
145664+
Ast_helper.Exp.apply ~loc unsafe_await [ (Nolabel, e) ]
145666145665

145667145666
end
145668145667
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
@@ -145137,14 +145137,12 @@ module Ast_async
145137145137
#1 "ast_async.ml"
145138145138
let add_promise_type ~async (result : Parsetree.expression) =
145139145139
if async then
145140-
let txt =
145141-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async")
145140+
let loc = result.pexp_loc in
145141+
let unsafe_async =
145142+
Ast_helper.Exp.ident ~loc
145143+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_async"); loc }
145142145144
in
145143-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = result.pexp_loc } in
145144-
{
145145-
result with
145146-
pexp_desc = Pexp_apply ({ result with pexp_desc }, [ (Nolabel, result) ]);
145147-
}
145145+
Ast_helper.Exp.apply ~loc unsafe_async [ (Nolabel, result) ]
145148145146
else result
145149145147

145150145148
let add_async_attribute ~async (body : Parsetree.expression) =
@@ -145167,7 +145165,7 @@ let rec add_promise_to_result (e : Parsetree.expression) =
145167145165
let make_function_async ~async (e : Parsetree.expression) =
145168145166
if async then
145169145167
match e.pexp_desc with
145170-
| Pexp_fun _ -> add_async_attribute ~async (add_promise_to_result e)
145168+
| Pexp_fun _ -> add_promise_to_result e
145171145169
| _ -> assert false
145172145170
else e
145173145171

@@ -145658,11 +145656,12 @@ module Ast_await
145658145656
= struct
145659145657
#1 "ast_await.ml"
145660145658
let create_await_expression (e : Parsetree.expression) =
145661-
let txt =
145662-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await")
145659+
let loc = e.pexp_loc in
145660+
let unsafe_await =
145661+
Ast_helper.Exp.ident ~loc
145662+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_await"); loc }
145663145663
in
145664-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
145665-
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
145664+
Ast_helper.Exp.apply ~loc unsafe_await [ (Nolabel, e) ]
145666145665

145667145666
end
145668145667
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
@@ -155421,14 +155421,12 @@ module Ast_async
155421155421
#1 "ast_async.ml"
155422155422
let add_promise_type ~async (result : Parsetree.expression) =
155423155423
if async then
155424-
let txt =
155425-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_async")
155424+
let loc = result.pexp_loc in
155425+
let unsafe_async =
155426+
Ast_helper.Exp.ident ~loc
155427+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_async"); loc }
155426155428
in
155427-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = result.pexp_loc } in
155428-
{
155429-
result with
155430-
pexp_desc = Pexp_apply ({ result with pexp_desc }, [ (Nolabel, result) ]);
155431-
}
155429+
Ast_helper.Exp.apply ~loc unsafe_async [ (Nolabel, result) ]
155432155430
else result
155433155431

155434155432
let add_async_attribute ~async (body : Parsetree.expression) =
@@ -155451,7 +155449,7 @@ let rec add_promise_to_result (e : Parsetree.expression) =
155451155449
let make_function_async ~async (e : Parsetree.expression) =
155452155450
if async then
155453155451
match e.pexp_desc with
155454-
| Pexp_fun _ -> add_async_attribute ~async (add_promise_to_result e)
155452+
| Pexp_fun _ -> add_promise_to_result e
155455155453
| _ -> assert false
155456155454
else e
155457155455

@@ -155942,11 +155940,12 @@ module Ast_await
155942155940
= struct
155943155941
#1 "ast_await.ml"
155944155942
let create_await_expression (e : Parsetree.expression) =
155945-
let txt =
155946-
Longident.Ldot (Longident.Ldot (Lident "Js", "Promise"), "unsafe_await")
155943+
let loc = e.pexp_loc in
155944+
let unsafe_await =
155945+
Ast_helper.Exp.ident ~loc
155946+
{ txt = Ldot (Ldot (Lident "Js", "Promise"), "unsafe_await"); loc }
155947155947
in
155948-
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
155949-
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
155948+
Ast_helper.Exp.apply ~loc unsafe_await [ (Nolabel, e) ]
155950155949

155951155950
end
155952155951
module Bs_ast_mapper : sig

0 commit comments

Comments
 (0)