diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b7e9adfb5..f7615554e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ #### :bug: Bug fix +- Fix partial application generalization for `...`. https://github.com/rescript-lang/rescript/pull/8343 + #### :memo: Documentation #### :nail_care: Polish diff --git a/compiler/ml/typecore.ml b/compiler/ml/typecore.ml index ee304dff7d..029f04b3a0 100644 --- a/compiler/ml/typecore.ml +++ b/compiler/ml/typecore.ml @@ -1803,6 +1803,11 @@ let rec is_nonexpansive exp = List.for_all (fun vb -> is_nonexpansive vb.vb_expr) pat_exp_list && is_nonexpansive body | Texp_function _ -> true + | Texp_apply {partial = true; _} -> + (* ReScript partial applications (`foo(args, ...)`) lower to wrapper + functions in codegen, so creating the partial itself is nonexpansive + like an explicit lambda. *) + true | Texp_apply {funct = e; args = (_, None) :: el} -> is_nonexpansive e && List.for_all is_nonexpansive_opt (List.map snd el) | Texp_match (e, cases, [], _) -> diff --git a/tests/tests/src/PartialApplicationNoRuntimeCurry.mjs b/tests/tests/src/PartialApplicationNoRuntimeCurry.mjs index aeae1808f3..8276e9759f 100644 --- a/tests/tests/src/PartialApplicationNoRuntimeCurry.mjs +++ b/tests/tests/src/PartialApplicationNoRuntimeCurry.mjs @@ -18,9 +18,18 @@ function add5(extra) { return 5 + extra | 0; } +function addHookPartial(extra) { + addHook(hook, extra); +} + +addHook(hook, _x => {}); + +addHook(hook, _x => {}); + export { f, add$1 as add, add5, + addHookPartial, } -/* No side effect */ +/* Not a pure module */ diff --git a/tests/tests/src/PartialApplicationNoRuntimeCurry.res b/tests/tests/src/PartialApplicationNoRuntimeCurry.res index 51eb8fa833..267dfc9544 100644 --- a/tests/tests/src/PartialApplicationNoRuntimeCurry.res +++ b/tests/tests/src/PartialApplicationNoRuntimeCurry.res @@ -9,3 +9,11 @@ let f = u => { type fn2 = (int, int) => int let add: fn2 = (a, b) => a + b let add5: int => int = add(5, ...) + +type hook +external hook: hook = "hook" +external addHook: (hook, 'a => unit) => unit = "addHook" + +let addHookPartial = addHook(hook, ...) +let _ = addHookPartial((_x: int) => ()) +let _ = addHookPartial((_x: string) => ())