`await` is rejected in a `@this async` function, which compiles to an `async function`
維護者通常 1 天內回覆
還沒有人認領這個 Issue。
評估
- 難度
- 3/5
- 預估耗時
- 1-2 天
- 新手友好度
- 72/100
- Issue 類型
- 缺陷
- 描述清晰度
- 描述清楚
- 活躍度
- 活躍
- 技術堆疊
- javascript, ocaml
研究方向
Start in compiler/frontend/bs_builtin_ppx.ml, where expr_mapper handles the Pexp_fun case with @this; compare its async_context handling with the plain Pexp_fun branch. Check the compiler tests for @this async functions and add coverage for await in the body. Done means the example compiles while await remains rejected in non-async @this functions and plain nested functions.
由索引模型根據 Issue 內容生成。
描述
An await in the body of a function that has both @this and async is rejected with "Await on expression not in an async context", although the function is typed as returning a promise and is compiled to a JavaScript async function.
type obj = {name: string}
let m = @this async (self: obj, x: promise<int>) => {
let v = await x
self.name ++ Int.toString(v)
}
We've found a bug for you!
ThisAsyncAwait.res:4:11-17
2 │
3 │ let m = @this async (self: obj, x: promise<int>) => {
4 │ let v = await x
5 │ self.name ++ Int.toString(v)
6 │ }
Await on expression not in an async context
Without the await, a @this async function has type @this (obj, int) => promise<string> and compiles to an async function, where await is valid:
let m = @this async (self: obj, x: int) => self.name ++ Int.toString(x)
async function m(x) {
let self = this ;
return self.name + x.toString();
}
module M = await List and for await x of xs {...} in the body of a @this async function are rejected with the same error. To use await, the body has to go into a separate async function that the method calls:
let helper = async (self: obj, x: promise<int>) => {
let v = await x
self.name ++ Int.toString(v)
}
let m = @this (self: obj, x: promise<int>) => helper(self, x)
async function helper(self, x) {
let v = await x;
return self.name + v.toString();
}
function m(x) {
let self = this ;
return helper(self, x);
}
In compiler/frontend/bs_builtin_ppx.ml, expr_mapper handles a Pexp_fun with @this (the Meth_callback case of Ast_attributes.process_attributes_rev) by setting async_context := false and then calling Ast_uncurry_gen.to_method_callback ~async, which maps the body under that context and builds the function with ~async and Ast_async.make_function_async ~async. So the body is checked as non-async even when the function it is emitted into is async. The false dates from when a @this function could not be async; #7702 passed ~async to to_method_callback but left the context unchanged. Setting async_context := async in that branch, as the plain Pexp_fun branch above it does, fixes it: the example at the top then compiles to async function m(x) with let v = await x;, and m.call({name: "n"}, Promise.resolve(41)) resolves to "n41". await in a @this function without async, or in a plain function inside a @this async one, is still rejected.
Reproduced with 12.0.0-beta.3, 12.3.1, 13.0.0-alpha.6 and master (fc7444266). A @this async function compiles to an async function with a promise result since #7702 (12.0.0-beta.3), the fix for #7681. Before that, in 12.0.0-beta.2 and 11.1.4, it compiled to a plain function, and await in it was rejected as well.
#6100 reported this error together with the dropped async attribute; #6105 fixed the attribute. Its first example, where the async function is the one returned by the @this function (@this self => async arg => await ...), compiles since 13.0.0-alpha.6; the form above, with @this and async on the same function, does not.
Related: #6100, #7681, #7702.
- 主要語言
- OCaml
- 星號
- 7.5k
- 分支
- 485
- 平均合併
- 16 小時 51 分鐘
- 30 天內合併 PR
- 268
環境準備
在瀏覽器裡用你自己的 GitHub 帳號啟動這個專案的開發容器。
- 沒有 Dockerfile 或 Docker Compose 檔案
- 有 Pull Request 範本
- 閱讀貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
rescript-lang/rescript 的其他 Issue
-
Exception analysis does not know the Temporal `fromStringOrThrow` functions可能已有人在做 @cknitt 於 3 天前認領。 未關閉
難度 2/5 1-3 小時 新手友好度 72/100
rescript-lang/rescript#9182 ·
維護者通常 1 天內回覆
-
Build system: make output wording and labels consistent可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉
難度 4/5 3-5 天 新手友好度 48/100
rescript-lang/rescript#9244 ·
維護者通常 1 天內回覆
-
rescript format: aborts on a syntax error, unstable output, raw compiler errors可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉
難度 4/5 3-5 天 新手友好度 56/100
rescript-lang/rescript#9243 ·
維護者通常 1 天內回覆
-
Build system CLI: behavior that disagrees with the help text可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉
難度 4/5 3-5 天 新手友好度 43/100
rescript-lang/rescript#9242 ·
維護者通常 1 天內回覆
-
Build system: a failed first build forces full rebuilds, and clean breaks a running watch可能已有人在做 關聯的 PR 仍在進行中或已合併。 未關閉
難度 4/5 3-5 天 新手友好度 52/100
rescript-lang/rescript#9241 ·
維護者通常 1 天內回覆
查看 rescript-lang/rescript 的全部 Issue
相似的 Issue
-
flang flang:runtime
難度 2/5 1-3 小時 新手友好度 86/100
llvm/llvm-project#239867 · 2 則留言 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 74/100
strawberry-graphql/strawberry#4794 ·
維護者通常 1 天內回覆
-
難度 2/5 1-3 小時 新手友好度 77/100
-
難度 2/5 1-3 小時 新手友好度 84/100
microsoft/TypeScript#65370 ·
維護者通常 1 天內回覆
-
Bug
難度 2/5 1-3 小時 新手友好度 72/100
維護者通常 1 天內回覆