From 25f64a495ad6698419fd15e0547940f80b7421f8 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 5 Sep 2025 17:45:45 +0200 Subject: [PATCH 1/3] syntax/jsx_v4: fix forwardRef arity regression; mark internal impl uncurried when forwardRef is used (#7738) - Fix JSX v4 React.forwardRef arity regression seen in v12. - When forwardRef is used, make the internal implementation uncurried with arity 2. - Add regression test tests/tests/src/forwardRef_regress.res (JSX v4 enabled). --- compiler/syntax/src/jsx_v4.ml | 5 +++++ tests/tests/src/forwardRef_regress.res | 8 ++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/tests/src/forwardRef_regress.res diff --git a/compiler/syntax/src/jsx_v4.ml b/compiler/syntax/src/jsx_v4.ml index 54f1ea8a2a..68f791ca7a 100644 --- a/compiler/syntax/src/jsx_v4.ml +++ b/compiler/syntax/src/jsx_v4.ml @@ -733,6 +733,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = | _ -> Pat.record (List.rev patterns_with_label) Open in let expression = + (* Shape internal implementation to match wrapper: uncurried when using forwardRef. *) Exp.fun_ ~arity:(Some 1) ~async:is_async Nolabel None (Pat.constraint_ record_pattern (Typ.constr ~loc:empty_loc @@ -748,6 +749,10 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = | _ -> [Typ.any ()])))) expression in + let expression = + if has_forward_ref then expression |> Ast_uncurried.uncurried_fun ~arity:2 + else expression + in let expression = (* Add new tupes (type a,b,c) to make's definition *) newtypes diff --git a/tests/tests/src/forwardRef_regress.res b/tests/tests/src/forwardRef_regress.res new file mode 100644 index 0000000000..3c81e51022 --- /dev/null +++ b/tests/tests/src/forwardRef_regress.res @@ -0,0 +1,8 @@ +@@config({flags: ["-bs-jsx", "4"]}) + +@react.component +let make = React.forwardRef((~className=?, ~children, _ref) => { + // Constrain type variables to avoid value restriction + let _: option = className + children +}) From 156cf1a88ab1e01f32e13fe04e573fc1b9def14e Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 5 Sep 2025 17:47:13 +0200 Subject: [PATCH 2/3] tests: add compiled .mjs for forwardRef_regress --- tests/tests/src/forwardRef_regress.mjs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 tests/tests/src/forwardRef_regress.mjs diff --git a/tests/tests/src/forwardRef_regress.mjs b/tests/tests/src/forwardRef_regress.mjs new file mode 100644 index 0000000000..4fd0066f78 --- /dev/null +++ b/tests/tests/src/forwardRef_regress.mjs @@ -0,0 +1,10 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as React from "react"; + +let make = React.forwardRef((props, ref) => props.children); + +export { + make, +} +/* make Not a pure module */ From cec32f5a23ac53683dd817b4ab3b703f6690a84b Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Fri, 5 Sep 2025 17:49:19 +0200 Subject: [PATCH 3/3] changelog: add entry for JSX v4 forwardRef arity fix (#7845) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c2dda552e..5d20016821 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ - JSX preserve mode: fix "make is not a valid component name". https://github.com/rescript-lang/rescript/pull/7831 - Rewatch: include parser arguments of experimental features. https://github.com/rescript-lang/rescript/pull/7836 - Stop mangling tagged templates and backquoted strings. https://github.com/rescript-lang/rescript/pull/7841 +- JSX v4: fix arity mismatch for `@react.component` with `React.forwardRef`. https://github.com/rescript-lang/rescript/pull/7845 #### :memo: Documentation