diff --git a/CHANGELOG.md b/CHANGELOG.md index ee12e337a5..74cdaf7ec3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - Rewatch: warnings for unsupported/unknown rescript.json fields. https://github.com/rescript-lang/rescript/pull/8031 - Fix missing `ignore` function in some Stdlib modules. https://github.com/rescript-lang/rescript/pull/8060 - Fix signature matching for externals when abstract alias hides function arity. https://github.com/rescript-lang/rescript/pull/8045 +- Fix arity detection for arrows returning nested generics. https://github.com/rescript-lang/rescript/pull/8064 #### :memo: Documentation diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 3718739c4b..a3dd8f981e 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -362,8 +362,10 @@ let is_es6_arrow_expression ~in_ternary p = (match state.Parser.token with (* arrived at `() :typ<` here *) | LessThan -> + Scanner.set_diamond_mode state.scanner; Parser.next state; - go_to_closing GreaterThan state + go_to_closing GreaterThan state; + Scanner.pop_mode state.scanner Diamond | _ -> ()); match state.Parser.token with (* arrived at `() :typ =>` or `() :typ<'a,'b> =>` here *) diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/arrow.res b/tests/syntax_tests/data/parsing/grammar/expressions/arrow.res index e13dd438e7..a382e1b52f 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/arrow.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/arrow.res @@ -107,4 +107,6 @@ let arr = (): array> => [] let fn = f => f; type f = int => unit; -let a = fn(_ => (): f); \ No newline at end of file +let a = fn(_ => (): f); + +let returnsArrayOption = (): option> => Some(["foo"]) diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/arrow.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/arrow.res.txt index aa9afaab35..7bc56d1e4b 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/arrow.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/arrow.res.txt @@ -74,7 +74,9 @@ type nonrec u = unit let un = (() : u) type nonrec ('a, 'b) d = ('a * 'b) let c [arity:1]() = ((1, 2) : ('a, 'b) d) -let arr () = ([||] : int nullable array) +let arr [arity:1]() = ([||] : int nullable array) let fn [arity:1]f = f type nonrec f = int -> unit (a:1) -let a = fn (fun [arity:1]_ -> () : f) \ No newline at end of file +let a = fn (fun [arity:1]_ -> () : f) +let returnsArrayOption [arity:1]() = + (Some [|{js|foo|js}|] : string array option) \ No newline at end of file diff --git a/tests/tests/src/nested_generic_return.mjs b/tests/tests/src/nested_generic_return.mjs new file mode 100644 index 0000000000..d319b249ec --- /dev/null +++ b/tests/tests/src/nested_generic_return.mjs @@ -0,0 +1,22 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function foo() { + return ["foo"]; +} + +let bar = ["foo"]; + +function nested() { + return 1; +} + +let baz = 1; + +export { + foo, + bar, + nested, + baz, +} +/* No side effect */ diff --git a/tests/tests/src/nested_generic_return.res b/tests/tests/src/nested_generic_return.res new file mode 100644 index 0000000000..e78702c3c2 --- /dev/null +++ b/tests/tests/src/nested_generic_return.res @@ -0,0 +1,7 @@ +// https://github.com/rescript-lang/rescript/issues/8055 + +let foo = (): option> => Some(["foo"]) +let bar = foo() + +let nested = (): option> => Some(Some(1)) +let baz = nested()