From 809a5fe10f9dec5ab6d1fb804b6f85fbf0dc3028 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Mon, 23 Dec 2024 08:27:00 +0100 Subject: [PATCH 1/4] AST cleanup: use inline record for Pexp_fun. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7df6fae7f..fd1b04b4d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,6 +49,7 @@ - AST cleanup: store arity in function type. https://github.com/rescript-lang/rescript/pull/7195 - AST cleanup: remove explicit uses of `function$` in preparation for removing the type entirely. https://github.com/rescript-lang/rescript/pull/7206 - AST cleanup: remove `function$` entirely. https://github.com/rescript-lang/rescript/pull/7208 +- AST cleanup: use inline record for Pexp_fun. https://github.com/rescript-lang/rescript/pull/7213 # 12.0.0-alpha.5 From 07c9d734a0511d0c17da5db44627e074d070513d Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Tue, 24 Dec 2024 08:33:58 +0100 Subject: [PATCH 2/4] AST: clean up async. --- compiler/frontend/ast_attributes.ml | 1 - compiler/frontend/ast_attributes.mli | 1 - compiler/frontend/bs_builtin_ppx.ml | 4 +- compiler/ml/ast_async.ml | 53 +++++++++----------- compiler/ml/translcore.ml | 8 ++- compiler/syntax/src/res_core.ml | 5 +- compiler/syntax/src/res_parsetree_viewer.ml | 11 ---- compiler/syntax/src/res_parsetree_viewer.mli | 6 --- compiler/syntax/src/res_printer.ml | 8 +-- 9 files changed, 34 insertions(+), 63 deletions(-) diff --git a/compiler/frontend/ast_attributes.ml b/compiler/frontend/ast_attributes.ml index 774da2c3f9..8de5322ac2 100644 --- a/compiler/frontend/ast_attributes.ml +++ b/compiler/frontend/ast_attributes.ml @@ -143,7 +143,6 @@ let is_inline : attr -> bool = fun ({txt}, _) -> txt = "inline" let has_inline_payload (attrs : t) = Ext_list.find_first attrs is_inline let has_await_payload (attrs : t) = Ext_list.find_first attrs Ast_await.is_await -let has_async_payload (attrs : t) = Ext_list.find_first attrs Ast_async.is_async type derive_attr = {bs_deriving: Ast_payload.action list option} [@@unboxed] diff --git a/compiler/frontend/ast_attributes.mli b/compiler/frontend/ast_attributes.mli index 91b151a30d..5a649683cd 100644 --- a/compiler/frontend/ast_attributes.mli +++ b/compiler/frontend/ast_attributes.mli @@ -36,7 +36,6 @@ val process_attributes_rev : t -> attr_kind * t val has_inline_payload : t -> attr option val has_await_payload : t -> attr option -val has_async_payload : t -> attr option type derive_attr = {bs_deriving: Ast_payload.action list option} [@@unboxed] diff --git a/compiler/frontend/bs_builtin_ppx.ml b/compiler/frontend/bs_builtin_ppx.ml index 0c78894cc0..14055b094a 100644 --- a/compiler/frontend/bs_builtin_ppx.ml +++ b/compiler/frontend/bs_builtin_ppx.ml @@ -111,12 +111,12 @@ let expr_mapper ~async_context ~in_function_def (self : mapper) {e with pexp_desc = Pexp_constant (Pconst_integer (s, None))} (* End rewriting *) | Pexp_newtype (s, body) -> - let async = Ast_attributes.has_async_payload e.pexp_attributes <> None in + let async = Ast_async.has_async_payload e.pexp_attributes in let body = Ast_async.add_async_attribute ~async body in let res = self.expr self body in {e with pexp_desc = Pexp_newtype (s, res)} | Pexp_fun {arg_label = label; lhs = pat; rhs = body} -> ( - let async = Ast_attributes.has_async_payload e.pexp_attributes <> None in + let async = Ast_async.has_async_payload e.pexp_attributes in match Ast_attributes.process_attributes_rev e.pexp_attributes with | Nothing, _ -> (* Handle @async x => y => ... is in async context *) diff --git a/compiler/ml/ast_async.ml b/compiler/ml/ast_async.ml index 49b64b9ca8..4dddf6b5a8 100644 --- a/compiler/ml/ast_async.ml +++ b/compiler/ml/ast_async.ml @@ -1,5 +1,27 @@ -let is_async : Parsetree.attribute -> bool = - fun ({txt}, _) -> txt = "async" || txt = "res.async" +let is_async : Parsetree.attribute -> bool = fun ({txt}, _) -> txt = "res.async" + +let has_async_payload attrs = Ext_list.exists attrs is_async + +let make_async_attr loc = (Location.mkloc "res.async" loc, Parsetree.PStr []) + +let add_async_attribute ~async (body : Parsetree.expression) = + if async then + { + body with + pexp_attributes = + ({txt = "res.async"; loc = Location.none}, PStr []) + :: body.pexp_attributes; + } + else body + +let extract_async_attribute attrs = + let rec process async acc attrs = + match attrs with + | [] -> (async, List.rev acc) + | ({Location.txt = "res.async"}, _) :: rest -> process true acc rest + | attr :: rest -> process async (attr :: acc) rest + in + process false [] attrs let add_promise_type ?(loc = Location.none) ~async (result : Parsetree.expression) = @@ -11,33 +33,6 @@ let add_promise_type ?(loc = Location.none) ~async Ast_helper.Exp.apply ~loc unsafe_async [(Nolabel, result)] else result -let add_async_attribute ~async (body : Parsetree.expression) = - if async then - match body.pexp_desc with - | Pexp_construct (x, Some e) when Ast_uncurried.expr_is_uncurried_fun body - -> - { - body with - pexp_desc = - Pexp_construct - ( x, - Some - { - e with - pexp_attributes = - ({txt = "res.async"; loc = Location.none}, PStr []) - :: e.pexp_attributes; - } ); - } - | _ -> - { - body with - pexp_attributes = - ({txt = "res.async"; loc = Location.none}, PStr []) - :: body.pexp_attributes; - } - else body - let rec add_promise_to_result ~loc (e : Parsetree.expression) = match e.pexp_desc with | Pexp_fun f -> diff --git a/compiler/ml/translcore.ml b/compiler/ml/translcore.ml index 1f34b5fde9..0ff4b76a28 100644 --- a/compiler/ml/translcore.ml +++ b/compiler/ml/translcore.ml @@ -652,9 +652,6 @@ let rec cut n l = let try_ids = Hashtbl.create 8 -let has_async_attribute exp = - exp.exp_attributes |> List.exists (fun ({txt}, _payload) -> txt = "res.async") - let extract_directive_for_fn exp = exp.exp_attributes |> List.find_map (fun ({txt}, payload) -> @@ -675,7 +672,7 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda = | Texp_let (rec_flag, pat_expr_list, body) -> transl_let rec_flag pat_expr_list (transl_exp body) | Texp_function {arg_label = _; arity; param; case; partial} -> ( - let async = has_async_attribute e in + let async = Ast_async.has_async_payload e.exp_attributes in let directive = match extract_directive_for_fn e with | None -> None @@ -1056,7 +1053,8 @@ and transl_function loc partial param case = }; } as exp; } - when Parmatch.inactive ~partial pat && not (exp |> has_async_attribute) -> + when Parmatch.inactive ~partial pat + && not (Ast_async.has_async_payload exp.exp_attributes) -> let params, body, return_unit = transl_function exp.exp_loc partial' param' case in diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 02c660b9d3..73443a3d8a 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -156,7 +156,6 @@ let jsx_attr = (Location.mknoloc "JSX", Parsetree.PStr []) let ternary_attr = (Location.mknoloc "res.ternary", Parsetree.PStr []) let if_let_attr = (Location.mknoloc "res.iflet", Parsetree.PStr []) let make_await_attr loc = (Location.mkloc "res.await" loc, Parsetree.PStr []) -let make_async_attr loc = (Location.mkloc "res.async" loc, Parsetree.PStr []) let suppress_fragile_match_warning_attr = ( Location.mknoloc "warning", Parsetree.PStr @@ -3321,7 +3320,9 @@ and parse_expr_block ?first p = and parse_async_arrow_expression ?(arrow_attrs = []) p = let start_pos = p.Parser.start_pos in Parser.expect (Lident "async") p; - let async_attr = make_async_attr (mk_loc start_pos p.prev_end_pos) in + let async_attr = + Ast_async.make_async_attr (mk_loc start_pos p.prev_end_pos) + in parse_es6_arrow_expression ~arrow_attrs:(async_attr :: arrow_attrs) ~arrow_start_pos:(Some start_pos) p diff --git a/compiler/syntax/src/res_parsetree_viewer.ml b/compiler/syntax/src/res_parsetree_viewer.ml index 3141bdd997..00265de2e3 100644 --- a/compiler/syntax/src/res_parsetree_viewer.ml +++ b/compiler/syntax/src/res_parsetree_viewer.ml @@ -86,17 +86,6 @@ let has_partial_attribute attrs = | _ -> false) attrs -type function_attributes_info = {async: bool; attributes: Parsetree.attributes} - -let process_function_attributes attrs = - let rec process async bs acc attrs = - match attrs with - | [] -> {async; attributes = List.rev acc} - | ({Location.txt = "res.async"}, _) :: rest -> process true bs acc rest - | attr :: rest -> process async bs (attr :: acc) rest - in - process false false [] attrs - let has_await_attribute attrs = List.exists (function diff --git a/compiler/syntax/src/res_parsetree_viewer.mli b/compiler/syntax/src/res_parsetree_viewer.mli index f478f1e633..eb89bc8b53 100644 --- a/compiler/syntax/src/res_parsetree_viewer.mli +++ b/compiler/syntax/src/res_parsetree_viewer.mli @@ -19,12 +19,6 @@ val process_partial_app_attribute : val has_partial_attribute : Parsetree.attributes -> bool -type function_attributes_info = {async: bool; attributes: Parsetree.attributes} - -(* determines whether a function is async and/or uncurried based on the given attributes *) -val process_function_attributes : - Parsetree.attributes -> function_attributes_info - val has_await_attribute : Parsetree.attributes -> bool val has_res_pat_variant_spread_attribute : Parsetree.attributes -> bool val has_dict_pattern_attribute : Parsetree.attributes -> bool diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index 3897ff4a21..03c888efa5 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -2694,9 +2694,7 @@ and print_if_chain ~state pexp_attributes ifs else_expr cmt_tbl = and print_expression ~state (e : Parsetree.expression) cmt_tbl = let print_arrow e = let attrs_on_arrow, parameters, return_expr = ParsetreeViewer.fun_expr e in - let ParsetreeViewer.{async; attributes = attrs} = - ParsetreeViewer.process_function_attributes attrs_on_arrow - in + let async, attrs = Ast_async.extract_async_attribute attrs_on_arrow in let return_expr, typ_constraint = match return_expr.pexp_desc with | Pexp_constraint (expr, typ) -> @@ -3437,9 +3435,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl = and print_pexp_fun ~state ~in_callback e cmt_tbl = let attrs_on_arrow, parameters, return_expr = ParsetreeViewer.fun_expr e in - let ParsetreeViewer.{async; attributes = attrs} = - ParsetreeViewer.process_function_attributes attrs_on_arrow - in + let async, attrs = Ast_async.extract_async_attribute attrs_on_arrow in let return_expr, typ_constraint = match return_expr.pexp_desc with | Pexp_constraint (expr, typ) -> From 0cf0b21ad1ccf7a928b084b57598d7cef832c65a Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Tue, 24 Dec 2024 08:38:27 +0100 Subject: [PATCH 3/4] Add more examples of async, attributes, and type abstractions. --- .../data/parsing/grammar/expressions/async.res | 7 +++++++ .../grammar/expressions/expected/async.res.txt | 11 ++++++++++- tests/syntax_tests/data/printer/expr/asyncAwait.res | 6 ++++++ .../data/printer/expr/expected/asyncAwait.res.txt | 6 ++++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/async.res b/tests/syntax_tests/data/parsing/grammar/expressions/async.res index 0a499bad5e..cde2152096 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/async.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/async.res @@ -35,3 +35,10 @@ let ex1 = await 3 + await 4 let ex2 = await 3 ** await 4 let ex3 = await foo->bar(~arg) let ex4 = await foo.bar.baz + + +let attr1 = @a async x => x+1 +let attr2 = @a async (type a) => (type b c, x) => 3 +let attr3 = @a (type a) => async (type b c, x) => 3 +let attr4 = @a (type a) => @b async (type b c, x) => 3 +let attr5 : int = @a @b async (type a, type b c) => (x:a) => x diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt index 8e560c579a..c782737397 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt @@ -31,4 +31,13 @@ let bar = ((fun [arity:1]~a:((a)[@res.namedArgLoc ]) -> a + 1)[@res.async ]) let ex1 = ((3)[@res.await ]) + ((4)[@res.await ]) let ex2 = ((3)[@res.await ]) ** ((4)[@res.await ]) let ex3 = ((foo |.u (bar ~arg:((arg)[@res.namedArgLoc ])))[@res.await ]) -let ex4 = (((foo.bar).baz)[@res.await ]) \ No newline at end of file +let ex4 = (((foo.bar).baz)[@res.await ]) +let attr1 = ((fun [arity:1]x -> x + 1)[@res.async ][@a ]) +let attr2 = ((fun (type a) -> fun (type b) -> fun (type c) -> + fun [arity:1]x -> 3)[@res.async ][@a ]) +let attr3 = ((fun (type a) -> ((fun (type b) -> fun (type c) -> + fun [arity:1]x -> 3)[@res.async ]))[@a ]) +let attr4 = ((fun (type a) -> ((fun (type b) -> fun (type c) -> + fun [arity:1]x -> 3)[@res.async ][@b ]))[@a ]) +let (attr5 : int) = ((fun (type a) -> fun (type b) -> fun (type c) -> + fun [arity:1](x : a) -> x)[@res.async ][@a ][@b ]) \ No newline at end of file diff --git a/tests/syntax_tests/data/printer/expr/asyncAwait.res b/tests/syntax_tests/data/printer/expr/asyncAwait.res index 870f770ba5..f3d6b14903 100644 --- a/tests/syntax_tests/data/printer/expr/asyncAwait.res +++ b/tests/syntax_tests/data/printer/expr/asyncAwait.res @@ -122,3 +122,9 @@ type t2 = (. int, string) => bool let f = async (type a, ()) => { await Js.Promise.resolve(()) } + +let attr1 = @a async x => x+1 +let attr2 = @a async (type a) => (type b c, x) => 3 +let attr3 = @a (type a) => async (type b c, x) => 3 +let attr4 = @a (type a) => @b async (type b c, x) => 3 +let attr5 : int => promise = @a @b async (type a, type b c) => (x:a) => x diff --git a/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt b/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt index 9141e4ff5b..36ac35ec82 100644 --- a/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt @@ -144,3 +144,9 @@ type t2 = (int, string) => bool let f = async (type a, ()) => { await Js.Promise.resolve() } + +let attr1 = @a async x => x + 1 +let attr2 = @a async (type a b c, x) => 3 +let attr3 = @a (type a, type b c, x) => 3 +let attr4 = @a (type a, @b type b c, x) => 3 +let attr5: int => promise = @a @b async (type a b c, x: a) => x From 6f9f6cf1af16fdafab26fe6a01f842089aa258c5 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Thu, 2 Jan 2025 10:39:07 +0100 Subject: [PATCH 4/4] Preserve the property of 1 function per `=>` in function definition. Before this diff `() => 3` would be a function but `(type a) => 3` would just be a number. Plus, `(type a) => (type b) => (x) => ...` would express a single function. Now, each `=>` represents a function (possibly adding a unit parameter when there are only types but no no term parameters). --- CHANGELOG.md | 1 - compiler/syntax/src/res_core.ml | 77 +++++++------------ compiler/syntax/src/res_parsetree_viewer.ml | 3 +- .../expected/UncurriedByDefault.res.txt | 6 +- .../expressions/expected/async.res.txt | 19 +++-- .../printer/comments/expected/expr.res.txt | 8 +- .../expr/expected/UncurriedByDefault.res.txt | 6 +- .../printer/expr/expected/asyncAwait.res.txt | 8 +- .../printer/expr/expected/newtype.res.txt | 11 +-- 9 files changed, 59 insertions(+), 80 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd1b04b4d0..e7df6fae7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -49,7 +49,6 @@ - AST cleanup: store arity in function type. https://github.com/rescript-lang/rescript/pull/7195 - AST cleanup: remove explicit uses of `function$` in preparation for removing the type entirely. https://github.com/rescript-lang/rescript/pull/7206 - AST cleanup: remove `function$` entirely. https://github.com/rescript-lang/rescript/pull/7208 -- AST cleanup: use inline record for Pexp_fun. https://github.com/rescript-lang/rescript/pull/7213 # 12.0.0-alpha.5 diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 73443a3d8a..4d36e7cd25 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -1731,7 +1731,12 @@ and parse_parameter_list p = ~f:parse_parameter ~closing:Rparen p in Parser.expect Rparen p; - parameters + let has_term_parameter = + Ext_list.exists parameters (function + | TermParameter _ -> true + | _ -> false) + in + (has_term_parameter, parameters) (* parameters ::= * | _ @@ -1742,6 +1747,22 @@ and parse_parameter_list p = *) and parse_parameters p = let start_pos = p.Parser.start_pos in + let unit_term_parameter () = + let loc = mk_loc start_pos p.Parser.prev_end_pos in + let unit_pattern = + Ast_helper.Pat.construct ~loc + (Location.mkloc (Longident.Lident "()") loc) + None + in + TermParameter + { + attrs = []; + label = Asttypes.Nolabel; + expr = None; + pat = unit_pattern; + pos = start_pos; + } + in match p.Parser.token with | Lident ident -> Parser.next p; @@ -1769,56 +1790,12 @@ and parse_parameters p = pos = start_pos; }; ] - | Lparen -> ( + | Lparen -> Parser.next p; - match p.Parser.token with - | Rparen -> - Parser.next p; - let loc = mk_loc start_pos p.Parser.prev_end_pos in - let unit_pattern = - Ast_helper.Pat.construct ~loc - (Location.mkloc (Longident.Lident "()") loc) - None - in - [ - TermParameter - { - attrs = []; - label = Asttypes.Nolabel; - expr = None; - pat = unit_pattern; - pos = start_pos; - }; - ] - | Dot -> ( - Parser.next p; - match p.token with - | Rparen -> - Parser.next p; - let loc = mk_loc start_pos p.Parser.prev_end_pos in - let unit_pattern = - Ast_helper.Pat.construct ~loc - (Location.mkloc (Longident.Lident "()") loc) - None - in - [ - TermParameter - { - attrs = []; - label = Asttypes.Nolabel; - expr = None; - pat = unit_pattern; - pos = start_pos; - }; - ] - | _ -> ( - match parse_parameter_list p with - | TermParameter p :: rest -> - TermParameter {p with pos = start_pos} :: rest - | TypeParameter p :: rest -> - TypeParameter {p with pos = start_pos} :: rest - | parameters -> parameters)) - | _ -> parse_parameter_list p) + ignore (Parser.optional p Dot); + let has_term_parameter, parameters = parse_parameter_list p in + if has_term_parameter then parameters + else parameters @ [unit_term_parameter ()] | token -> Parser.err p (Diagnostics.unexpected token p.breadcrumbs); [] diff --git a/compiler/syntax/src/res_parsetree_viewer.ml b/compiler/syntax/src/res_parsetree_viewer.ml index 00265de2e3..1746c02e5f 100644 --- a/compiler/syntax/src/res_parsetree_viewer.ml +++ b/compiler/syntax/src/res_parsetree_viewer.ml @@ -187,7 +187,8 @@ let fun_expr expr = }; } -> (attrs_before, List.rev acc, rewrite_underscore_apply expr) - | {pexp_desc = Pexp_newtype (string_loc, rest); pexp_attributes = attrs} -> + | {pexp_desc = Pexp_newtype (string_loc, rest); pexp_attributes = attrs} + when n_fun = 0 -> let string_locs, return_expr = collect_new_types [string_loc] rest in let param = NewTypes {attrs; locs = string_locs} in collect ~n_fun attrs_before (param :: acc) return_expr diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/UncurriedByDefault.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/UncurriedByDefault.res.txt index 873c89937e..d2a3bf9c58 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/UncurriedByDefault.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/UncurriedByDefault.res.txt @@ -44,9 +44,9 @@ let t0 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l let t1 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l let t2 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l let t3 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l -let t4 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l -let t5 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l -let t6 (type a) (type b) [arity:2](l : a list) (x : a) = x :: l +let t4 (type a) (type b) [arity:1]() [arity:2](l : a list) (x : a) = x :: l +let t5 (type a) (type b) [arity:1]() [arity:2](l : a list) (x : a) = x :: l +let t6 (type a) (type b) [arity:1]() [arity:2](l : a list) (x : a) = x :: l type nonrec arrowPath1 = int -> string (a:1) type nonrec arrowPath2 = I.t -> string (a:1) type nonrec arrowPath3 = int -> string (a:1) diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt index c782737397..bfa4292396 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/async.res.txt @@ -33,11 +33,16 @@ let ex2 = ((3)[@res.await ]) ** ((4)[@res.await ]) let ex3 = ((foo |.u (bar ~arg:((arg)[@res.namedArgLoc ])))[@res.await ]) let ex4 = (((foo.bar).baz)[@res.await ]) let attr1 = ((fun [arity:1]x -> x + 1)[@res.async ][@a ]) -let attr2 = ((fun (type a) -> fun (type b) -> fun (type c) -> - fun [arity:1]x -> 3)[@res.async ][@a ]) -let attr3 = ((fun (type a) -> ((fun (type b) -> fun (type c) -> - fun [arity:1]x -> 3)[@res.async ]))[@a ]) -let attr4 = ((fun (type a) -> ((fun (type b) -> fun (type c) -> - fun [arity:1]x -> 3)[@res.async ][@b ]))[@a ]) +let attr2 = ((fun (type a) -> + fun [arity:1]() -> fun (type b) -> fun (type c) -> fun [arity:1]x -> 3) + [@res.async ][@a ]) +let attr3 = ((fun (type a) -> + fun [arity:1]() -> ((fun (type b) -> fun (type c) -> fun [arity:1]x -> 3) + [@res.async ])) + [@a ]) +let attr4 = ((fun (type a) -> + fun [arity:1]() -> ((fun (type b) -> fun (type c) -> fun [arity:1]x -> 3) + [@res.async ][@b ])) + [@a ]) let (attr5 : int) = ((fun (type a) -> fun (type b) -> fun (type c) -> - fun [arity:1](x : a) -> x)[@res.async ][@a ][@b ]) \ No newline at end of file + fun [arity:1]() -> fun [arity:1](x : a) -> x)[@res.async ][@a ][@b ]) \ No newline at end of file diff --git a/tests/syntax_tests/data/printer/comments/expected/expr.res.txt b/tests/syntax_tests/data/printer/comments/expected/expr.res.txt index 1085861c82..5b5cbccd83 100644 --- a/tests/syntax_tests/data/printer/comments/expected/expr.res.txt +++ b/tests/syntax_tests/data/printer/comments/expected/expr.res.txt @@ -227,12 +227,8 @@ let f = ( ) => /* c7 */ () let multiply = (type /* c-2 */ t /* c-1 */, /* c0 */ m1 /* c1 */, /* c2 */ m2 /* c3 */) => () -let multiply = ( - type /* c-4 */ t /* c-3 */, - /* c0 */ m1 /* c1 */, - type /* c-2 */ s /* c-1 */, - /* c2 */ m2 /* c3 */, -) => () +let multiply = (type /* c-4 */ t /* c-3 */, /* c0 */ m1 /* c1 */) => + (type /* c-2 */ s /* c-1 */, /* c2 */ m2 /* c3 */) => () f( // a diff --git a/tests/syntax_tests/data/printer/expr/expected/UncurriedByDefault.res.txt b/tests/syntax_tests/data/printer/expr/expected/UncurriedByDefault.res.txt index dd3e211701..1c9db31945 100644 --- a/tests/syntax_tests/data/printer/expr/expected/UncurriedByDefault.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/UncurriedByDefault.res.txt @@ -53,9 +53,9 @@ let t0 = (type a b, l: list, x: a) => list{x, ...l} let t1 = (type a b, l: list, x: a) => list{x, ...l} let t2 = (type a b, l: list, x: a) => list{x, ...l} let t3 = (type a b, l: list, x: a) => list{x, ...l} -let t4 = (type a b, l: list, x: a) => list{x, ...l} -let t5 = (type a b, l: list, x: a) => list{x, ...l} -let t6 = (type a b, l: list, x: a) => list{x, ...l} +let t4 = (type a b, ()) => (l: list, x: a) => list{x, ...l} +let t5 = (type a b, ()) => (l: list, x: a) => list{x, ...l} +let t6 = (type a b, ()) => (l: list, x: a) => list{x, ...l} let () = (x => ignore(x))(3) let () = (x => ignore(x))(3) diff --git a/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt b/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt index 36ac35ec82..5acc579bd1 100644 --- a/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/asyncAwait.res.txt @@ -146,7 +146,7 @@ let f = async (type a, ()) => { } let attr1 = @a async x => x + 1 -let attr2 = @a async (type a b c, x) => 3 -let attr3 = @a (type a, type b c, x) => 3 -let attr4 = @a (type a, @b type b c, x) => 3 -let attr5: int => promise = @a @b async (type a b c, x: a) => x +let attr2 = @a async (type a, ()) => (type b c, x) => 3 +let attr3 = @a (type a, ()) => async (type b c, x) => 3 +let attr4 = @a (type a, ()) => @b async (type b c, x) => 3 +let attr5: int => promise = @a @b async (type a b c, ()) => (x: a) => x diff --git a/tests/syntax_tests/data/printer/expr/expected/newtype.res.txt b/tests/syntax_tests/data/printer/expr/expected/newtype.res.txt index 39dc430d9b..5ba8123497 100644 --- a/tests/syntax_tests/data/printer/expr/expected/newtype.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/newtype.res.txt @@ -1,13 +1,14 @@ let f = (type t, xs: list) => () let f = @attr (type t, xs: list) => () -let f = (type t, xs: list, type s, ys: list) => () -let f = @attr (type t, xs: list, @attr2 type s, ys: list) => () +let f = (type t, xs: list) => (type s, ys: list) => () +let f = @attr (type t, xs: list) => @attr2 (type s, ys: list) => () let f = (type t u v, xs: list<(t, u, v)>) => () let f = @attr (type t u v, xs: list<(t, u, v)>) => () -let f = (type t u v, xs: list<(t, u, v)>, type s w z, ys: list<(s, w, z)>) => () -let f = @attr (type t u v, xs: list<(t, u, v)>, @attr2 type s w z, ys: list<(s, w, z)>) => () +let f = (type t u v, xs: list<(t, u, v)>) => (type s w z, ys: list<(s, w, z)>) => () +let f = @attr (type t u v, xs: list<(t, u, v)>) => @attr2 (type s w z, ys: list<(s, w, z)>) => () let f = @attr -(type t, @attr type s, xs: list<(t, s)>, @attr type u, @attr type v w, ys: list<(u, v, w)>) => () +(type t, @attr type s, xs: list<(t, s)>) => + @attr (type u, @attr type v w, ys: list<(u, v, w)>) => () let mk_formatting_gen: type a b c d e f. formatting_gen => Parsetree.expression =