Partial application moves its arguments into the generated closure
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 初心者へのやさしさ
- 25/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 停滞
- 技術スタック
- javascript
- 領域
- compilers
調査の方向性
Start in compiler/ml/translcore.ml at transl_apply's uncurried_partial_application branch, then compare its argument handling with build_apply's protect path. Check the compiler tests for partial application, including cases with await, side effects, and yield. Done means arguments are evaluated once at the partial application site and remain valid outside the generated closure.
索引モデルが issue の本文から書いたものです。
説明
Partial application with ... puts the supplied arguments inside the closure it creates, instead of evaluating them first.
let add = (a, b, c) => a + b + c
let f = async p => {
let h = add(await p, ...)
h(1, 2) + h(3, 4)
}
compiles to
async function f(p) {
let h = (extra, extra$1) => add(await p, extra, extra$1);
return h(1, 2) + h(3, 4) | 0;
}
await inside a non-async arrow is a JavaScript syntax error, so the module fails to load.
The same placement also re-evaluates the argument on every call:
let g = () => {
let h = add(next(), ...)
h(1, 2) + h(1, 2)
}
function g() {
let h = (extra, extra$1) => add(next(), extra, extra$1);
return h(1, 2) + h(1, 2) | 0;
}
Here next() runs twice, once for each call of h.
When h is used only once, the optimizer inlines it and both problems disappear, which may be why this hasn't been noticed.
Expected: the arguments are evaluated once, where the partial application happens:
let arg = await p;
let h = (extra, extra$1) => add(arg, extra, extra$1);
Cause: in compiler/ml/translcore.ml, transl_apply's uncurried_partial_application branch puts the translated arguments directly into the body of the new function. The optional-argument path (build_apply) already let-binds non-trivial arguments outside the closure (protect); the ... path should do the same.
This also blocks generator functions, since a yield would be moved into the closure the same way.
Reproduced on master (8556f0ad72).
- 主要言語
- ReScript
- スター
- 7.5k
- フォーク
- 483
- 平均マージ
- 1日 2時間
- マージ済み PR(30日)
- 164
環境構築
このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
rescript-lang/rescript のほかの issue
-
難易度 4/5 3〜5日 初心者へのやさしさ 48/100
rescript-lang/rescript#8938 ·
メンテナーはふだん 1 日以内に返信
-
discussion enhancement
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
rescript-lang/rescript#8934 · リアクション 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
rescript-lang/rescript#8910 ·
メンテナーはふだん 1 日以内に返信
-
Nested JSX components under React Server Components: derive flat exports from the signature対応中かも @cknitt が 3 日前に担当しました。 オープン
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
rescript-lang/rescript#8901 ·
メンテナーはふだん 1 日以内に返信
-
難易度 5/5 1週間以上 初心者へのやさしさ 35/100
rescript-lang/rescript#8897 ·
メンテナーはふだん 1 日以内に返信
rescript-lang/rescript の issue をすべて見る
似ている issue
-
bug priority: P2
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
confirmed generated by fuzzer llvm:optimizations miscompilation
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
llvm/llvm-project#234325 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
gren-lang/compiler-common#41 ·
-
area:codegen backend:hlsl bug coverage direction:output
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信