diff --git a/CHANGELOG.md b/CHANGELOG.md index 5234be8b7d..c46e0de4dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ - Editor: Fix issue where pipe completions would not trigger with generic type arguments. https://github.com/rescript-lang/rescript/pull/7231 - Fix leftover assert false in code for `null != undefined`. https://github.com/rescript-lang/rescript/pull/7232 +#### :house: Internal + +- AST cleanup: Prepare for ast async cleanup: Refactor code for "@res.async" payload handling and clean up handling of type and term parameters, so that now each `=>` in a function definition corresponds to a function. https://github.com/rescript-lang/rescript/pull/7223 +- AST: always put type parameters first in function definitions. https://github.com/rescript-lang/rescript/pull/7233 + # 12.0.0-alpha.7 #### :bug: Bug fix diff --git a/compiler/frontend/bs_builtin_ppx.ml b/compiler/frontend/bs_builtin_ppx.ml index 14055b094a..34d7835cec 100644 --- a/compiler/frontend/bs_builtin_ppx.ml +++ b/compiler/frontend/bs_builtin_ppx.ml @@ -111,8 +111,6 @@ 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_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} -> ( diff --git a/compiler/ml/ast_async.ml b/compiler/ml/ast_async.ml index 4dddf6b5a8..f102660066 100644 --- a/compiler/ml/ast_async.ml +++ b/compiler/ml/ast_async.ml @@ -1,28 +1,34 @@ -let is_async : Parsetree.attribute -> bool = fun ({txt}, _) -> txt = "res.async" +let has_async_payload attrs = + Ext_list.exists attrs (fun ({Location.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 rec dig_async_payload_from_function (expr : Parsetree.expression) = + match expr.pexp_desc with + | Pexp_fun _ -> has_async_payload expr.pexp_attributes + | Pexp_newtype (_, body) -> dig_async_payload_from_function body + | _ -> false let add_async_attribute ~async (body : Parsetree.expression) = + let add (exp : Parsetree.expression) = + if has_async_payload exp.pexp_attributes then exp + else + { + exp with + pexp_attributes = + ({txt = "res.async"; loc = Location.none}, PStr []) + :: exp.pexp_attributes; + } + in if async then - { - body with - pexp_attributes = - ({txt = "res.async"; loc = Location.none}, PStr []) - :: body.pexp_attributes; - } + let rec add_to_fun (exp : Parsetree.expression) = + match exp.pexp_desc with + | Pexp_newtype (txt, e) -> + {exp with pexp_desc = Pexp_newtype (txt, add_to_fun e)} + | Pexp_fun _ -> add exp + | _ -> exp + in + add_to_fun body 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) = if async then diff --git a/compiler/syntax/src/jsx_common.ml b/compiler/syntax/src/jsx_common.ml index 41a7fc685c..20f0c61413 100644 --- a/compiler/syntax/src/jsx_common.ml +++ b/compiler/syntax/src/jsx_common.ml @@ -50,22 +50,6 @@ let raise_error_multiple_component ~loc = "Only one component definition is allowed for each module. Move to a \ submodule or other file if necessary." -let remove_arity binding = - let rec remove_arity_record expr = - match expr.pexp_desc with - | _ when Ast_uncurried.expr_is_uncurried_fun expr -> - Ast_uncurried.expr_extract_uncurried_fun expr - | Pexp_newtype (label, e) -> - {expr with pexp_desc = Pexp_newtype (label, remove_arity_record e)} - | Pexp_apply (forward_ref, [(label, e)]) -> - { - expr with - pexp_desc = Pexp_apply (forward_ref, [(label, remove_arity_record e)]); - } - | _ -> expr - in - {binding with pvb_expr = remove_arity_record binding.pvb_expr} - let async_component ~async expr = if async then let open Ast_helper in diff --git a/compiler/syntax/src/jsx_v4.ml b/compiler/syntax/src/jsx_v4.ml index 574d1efe7a..c0b31afe31 100644 --- a/compiler/syntax/src/jsx_v4.ml +++ b/compiler/syntax/src/jsx_v4.ml @@ -927,7 +927,6 @@ let vb_match_expr named_arg_list expr = let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = if Jsx_common.has_attr_on_binding Jsx_common.has_attr binding then ( check_multiple_components ~config ~loc:pstr_loc; - let binding = Jsx_common.remove_arity binding in let core_type_of_attr = Jsx_common.core_type_of_attrs binding.pvb_attributes in @@ -954,11 +953,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = let binding_wrapper, has_forward_ref, expression = modified_binding ~binding_loc ~binding_pat_loc ~fn_name binding in - let is_async = - Ext_list.find_first binding.pvb_expr.pexp_attributes Ast_async.is_async - |> Option.is_some - in - (* do stuff here! *) + let is_async = Ast_async.dig_async_payload_from_function binding.pvb_expr in let named_arg_list, newtypes, _typeConstraints = recursively_transform_named_args_for_make (modified_binding_old binding) @@ -1177,12 +1172,10 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = (Some props_record_type, binding, new_binding)) else if Jsx_common.has_attr_on_binding Jsx_common.has_attr_with_props binding then - let modified_binding = Jsx_common.remove_arity binding in let modified_binding = { - modified_binding with - pvb_attributes = - modified_binding.pvb_attributes |> List.filter other_attrs_pure; + binding with + pvb_attributes = binding.pvb_attributes |> List.filter other_attrs_pure; } in let fn_name = get_fn_name modified_binding.pvb_pat in @@ -1192,9 +1185,7 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding = in let is_async = - Ext_list.find_first modified_binding.pvb_expr.pexp_attributes - Ast_async.is_async - |> Option.is_some + Ast_async.dig_async_payload_from_function modified_binding.pvb_expr in let make_new_binding ~loc ~full_module_name binding = diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 4d36e7cd25..7a1fbeb610 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -7,13 +7,6 @@ module ResPrinter = Res_printer module Scanner = Res_scanner module Parser = Res_parser -module LoopProgress = struct - let list_rest list = - match list with - | [] -> assert false - | _ :: rest -> rest -end - let mk_loc start_loc end_loc = Location.{loc_start = start_loc; loc_end = end_loc; loc_ghost = false} @@ -189,19 +182,24 @@ type typ_def_or_ext = } | TypeExt of Parsetree.type_extension -type labelled_parameter = - | TermParameter of { - attrs: Parsetree.attributes; - label: Asttypes.arg_label; - expr: Parsetree.expression option; - pat: Parsetree.pattern; - pos: Lexing.position; - } - | TypeParameter of { - attrs: Parsetree.attributes; - locs: string Location.loc list; - pos: Lexing.position; - } +type fundef_type_param = { + attrs: Parsetree.attributes; + locs: string Location.loc list; + p_pos: Lexing.position; +} + +type fundef_term_param = { + attrs: Parsetree.attributes; + p_label: Asttypes.arg_label; + expr: Parsetree.expression option; + pat: Parsetree.pattern; + p_pos: Lexing.position; +} + +(* Single parameter of a function definition (type a b, x, ~y) *) +type fundef_parameter = + | TermParameter of fundef_term_param + | TypeParameter of fundef_type_param type record_pattern_item = | PatUnderscore @@ -209,6 +207,28 @@ type record_pattern_item = type context = OrdinaryExpr | TernaryTrueBranchExpr | WhenExpr +(* Extracts type and term parameters from a list of function definition parameters, combining all type parameters into one *) +let rec extract_fundef_params ~(type_acc : fundef_type_param option) + ~(term_acc : fundef_term_param list) (params : fundef_parameter list) : + fundef_type_param option * fundef_term_param list = + match params with + | TermParameter tp :: rest -> + extract_fundef_params ~type_acc ~term_acc:(tp :: term_acc) rest + | TypeParameter tp :: rest -> + let type_acc = + match type_acc with + | Some tpa -> + Some + { + attrs = tpa.attrs @ tp.attrs; + locs = tpa.locs @ tp.locs; + p_pos = tpa.p_pos; + } + | None -> Some tp + in + extract_fundef_params ~type_acc ~term_acc rest + | [] -> (type_acc, List.rev term_acc) + let get_closing_token = function | Token.Lparen -> Token.Rparen | Lbrace -> Rbrace @@ -1517,7 +1537,7 @@ and parse_ternary_expr left_operand p = | _ -> left_operand and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None) - ?context ?parameters p = + ?context ?term_parameters p = let start_pos = p.Parser.start_pos in Parser.leave_breadcrumb p Grammar.Es6ArrowExpr; (* Parsing function parameters and attributes: @@ -1527,8 +1547,8 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None) 2. Attributes inside `(...)` are added to the arguments regardless of whether labeled, optional or nolabeled *) let parameters = - match parameters with - | Some params -> params + match term_parameters with + | Some params -> (None, params) | None -> parse_parameters p in let parameters = @@ -1539,28 +1559,23 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None) | None -> pos in match parameters with - | TermParameter p :: rest -> - TermParameter - {p with attrs = update_attrs p.attrs; pos = update_pos p.pos} - :: rest - | TypeParameter p :: rest -> - TypeParameter - {p with attrs = update_attrs p.attrs; pos = update_pos p.pos} - :: rest - | [] -> parameters - in - let parameters = - (* Propagate any dots from type parameters to the first term *) - let rec loop ~dot_in_type params = - match params with - | (TypeParameter _ as p) :: _ -> - let rest = LoopProgress.list_rest params in - (* Tell termination checker about progress *) - p :: loop ~dot_in_type rest - | (TermParameter _ as p) :: rest -> p :: rest - | [] -> [] - in - loop ~dot_in_type:false parameters + | None, termp :: rest -> + ( None, + { + termp with + attrs = update_attrs termp.attrs; + p_pos = update_pos termp.p_pos; + } + :: rest ) + | Some (tpa : fundef_type_param), term_params -> + ( Some + { + tpa with + attrs = update_attrs tpa.attrs; + p_pos = update_pos tpa.p_pos; + }, + term_params ) + | _ -> parameters in let return_type = match p.Parser.token with @@ -1581,32 +1596,26 @@ and parse_es6_arrow_expression ?(arrow_attrs = []) ?(arrow_start_pos = None) in Parser.eat_breadcrumb p; let end_pos = p.prev_end_pos in - let term_parameters = - parameters - |> List.filter (function - | TermParameter _ -> true - | TypeParameter _ -> false) - in - let _paramNum, arrow_expr, _arity = + let type_param_opt, term_parameters = parameters in + let arrow_expr = List.fold_right - (fun parameter (term_param_num, expr, arity) -> - match parameter with - | TermParameter - {attrs; label = lbl; expr = default_expr; pat; pos = start_pos} -> - let loc = mk_loc start_pos end_pos in - let fun_expr = - Ast_helper.Exp.fun_ ~loc ~attrs ~arity:None lbl default_expr pat - expr - in - if term_param_num = 1 then - (term_param_num - 1, Ast_uncurried.uncurried_fun ~arity fun_expr, 1) - else (term_param_num - 1, fun_expr, arity + 1) - | TypeParameter {attrs; locs = newtypes; pos = start_pos} -> - ( term_param_num, - make_newtypes ~attrs ~loc:(mk_loc start_pos end_pos) newtypes expr, - arity )) - parameters - (List.length term_parameters, body, 1) + (fun parameter expr -> + let {attrs; p_label = lbl; expr = default_expr; pat; p_pos = start_pos} + = + parameter + in + let loc = mk_loc start_pos end_pos in + Ast_helper.Exp.fun_ ~loc ~attrs ~arity:None lbl default_expr pat expr) + term_parameters body + in + let arrow_expr = + Ast_uncurried.uncurried_fun ~arity:(List.length term_parameters) arrow_expr + in + let arrow_expr = + match type_param_opt with + | None -> arrow_expr + | Some {attrs; locs = newtypes; p_pos = start_pos} -> + make_newtypes ~attrs ~loc:(mk_loc start_pos end_pos) newtypes arrow_expr in {arrow_expr with pexp_loc = {arrow_expr.pexp_loc with loc_start = start_pos}} @@ -1640,7 +1649,7 @@ and parse_parameter p = if p.Parser.token = Typ then ( Parser.next p; let lidents = parse_lident_list p in - Some (TypeParameter {attrs; locs = lidents; pos = start_pos})) + Some (TypeParameter {attrs; locs = lidents; p_pos = start_pos})) else let attrs, lbl, pat = match p.Parser.token with @@ -1714,15 +1723,17 @@ and parse_parameter p = Parser.next p; Some (TermParameter - {attrs; label = lbl; expr = None; pat; pos = start_pos}) + {attrs; p_label = lbl; expr = None; pat; p_pos = start_pos}) | _ -> let expr = parse_constrained_or_coerced_expr p in Some (TermParameter - {attrs; label = lbl; expr = Some expr; pat; pos = start_pos})) + {attrs; p_label = lbl; expr = Some expr; pat; p_pos = start_pos}) + ) | _ -> Some - (TermParameter {attrs; label = lbl; expr = None; pat; pos = start_pos}) + (TermParameter + {attrs; p_label = lbl; expr = None; pat; p_pos = start_pos}) else None and parse_parameter_list p = @@ -1731,12 +1742,7 @@ and parse_parameter_list p = ~f:parse_parameter ~closing:Rparen p in Parser.expect Rparen p; - let has_term_parameter = - Ext_list.exists parameters (function - | TermParameter _ -> true - | _ -> false) - in - (has_term_parameter, parameters) + extract_fundef_params ~type_acc:None ~term_acc:[] parameters (* parameters ::= * | _ @@ -1745,7 +1751,7 @@ and parse_parameter_list p = * | (.) * | ( parameter {, parameter} [,] ) *) -and parse_parameters p = +and parse_parameters p : fundef_type_param option * fundef_term_param list = let start_pos = p.Parser.start_pos in let unit_term_parameter () = let loc = mk_loc start_pos p.Parser.prev_end_pos in @@ -1754,51 +1760,52 @@ and parse_parameters p = (Location.mkloc (Longident.Lident "()") loc) None in - TermParameter - { - attrs = []; - label = Asttypes.Nolabel; - expr = None; - pat = unit_pattern; - pos = start_pos; - } + { + attrs = []; + p_label = Asttypes.Nolabel; + expr = None; + pat = unit_pattern; + p_pos = start_pos; + } in match p.Parser.token with | Lident ident -> Parser.next p; let loc = mk_loc start_pos p.Parser.prev_end_pos in - [ - TermParameter + ( None, + [ { attrs = []; - label = Asttypes.Nolabel; + p_label = Asttypes.Nolabel; expr = None; pat = Ast_helper.Pat.var ~loc (Location.mkloc ident loc); - pos = start_pos; + p_pos = start_pos; }; - ] + ] ) | Underscore -> Parser.next p; let loc = mk_loc start_pos p.Parser.prev_end_pos in - [ - TermParameter + ( None, + [ { attrs = []; - label = Asttypes.Nolabel; + p_label = Asttypes.Nolabel; expr = None; pat = Ast_helper.Pat.any ~loc (); - pos = start_pos; + p_pos = start_pos; }; - ] + ] ) | Lparen -> Parser.next 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 ()] + let type_params, term_params = parse_parameter_list p in + let term_params = + if term_params <> [] then term_params else [unit_term_parameter ()] + in + (type_params, term_params) | token -> Parser.err p (Diagnostics.unexpected token p.breadcrumbs); - [] + (None, []) and parse_coerced_expr ~(expr : Parsetree.expression) p = Parser.expect ColonGreaterThan p; @@ -2994,16 +3001,15 @@ and parse_braced_or_record_expr p = let ident = Location.mkloc (Longident.last path_ident.txt) loc in let a = parse_es6_arrow_expression - ~parameters: + ~term_parameters: [ - TermParameter - { - attrs = []; - label = Asttypes.Nolabel; - expr = None; - pat = Ast_helper.Pat.var ~loc:ident.loc ident; - pos = start_pos; - }; + { + attrs = []; + p_label = Asttypes.Nolabel; + expr = None; + pat = Ast_helper.Pat.var ~loc:ident.loc ident; + p_pos = start_pos; + }; ] p in @@ -3297,12 +3303,8 @@ 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 = - 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 + Ast_async.add_async_attribute ~async:true + (parse_es6_arrow_expression ~arrow_attrs ~arrow_start_pos:(Some start_pos) p) and parse_await_expression p = let await_loc = mk_loc p.Parser.start_pos p.end_pos in @@ -5749,7 +5751,7 @@ and parse_structure_item_region p = ~loc:(mk_loc p.start_pos p.prev_end_pos) ~attrs expr) | _ -> None) -[@@progress Parser.next, Parser.expect, LoopProgress.list_rest] +[@@progress Parser.next, Parser.expect] (* include-statement ::= include module-expr *) and parse_include_statement ~attrs p = @@ -6402,7 +6404,7 @@ and parse_signature_item_region p = (Diagnostics.message (ErrorMessages.attribute_without_node attr)); Some Recover.default_signature_item | _ -> None) -[@@progress Parser.next, Parser.expect, LoopProgress.list_rest] +[@@progress Parser.next, Parser.expect] (* module rec module-name : module-type { and module-name: module-type } *) and parse_rec_module_spec ~attrs ~start_pos p = diff --git a/compiler/syntax/src/res_parens.ml b/compiler/syntax/src/res_parens.ml index 786afca935..af8b4b2160 100644 --- a/compiler/syntax/src/res_parens.ml +++ b/compiler/syntax/src/res_parens.ml @@ -301,9 +301,7 @@ let ternary_operand expr = Nothing | {pexp_desc = Pexp_constraint _} -> Parenthesized | _ when Res_parsetree_viewer.is_fun_newtype expr -> ( - let _attrsOnArrow, _parameters, return_expr = - ParsetreeViewer.fun_expr expr - in + let _, _parameters, return_expr = ParsetreeViewer.fun_expr expr in match return_expr.pexp_desc with | Pexp_constraint _ -> Parenthesized | _ -> Nothing) diff --git a/compiler/syntax/src/res_parsetree_viewer.ml b/compiler/syntax/src/res_parsetree_viewer.ml index 1746c02e5f..7331d89ef4 100644 --- a/compiler/syntax/src/res_parsetree_viewer.ml +++ b/compiler/syntax/src/res_parsetree_viewer.ml @@ -165,33 +165,10 @@ type fun_param_kind = } | NewTypes of {attrs: Parsetree.attributes; locs: string Asttypes.loc list} -let fun_expr expr = - (* Turns (type t, type u, type z) into "type t u z" *) - let rec collect_new_types acc return_expr = - match return_expr with - | {pexp_desc = Pexp_newtype (string_loc, return_expr); pexp_attributes = []} - -> - collect_new_types (string_loc :: acc) return_expr - | return_expr -> (List.rev acc, return_expr) - in - let rec collect ~n_fun attrs_before acc expr = +let fun_expr expr_ = + let async = Ast_async.dig_async_payload_from_function expr_ in + let rec collect_params ~n_fun ~params expr = match expr with - | { - pexp_desc = - Pexp_fun - { - arg_label = Nolabel; - default = None; - lhs = {ppat_desc = Ppat_var {txt = "__x"}}; - rhs = {pexp_desc = Pexp_apply _}; - }; - } -> - (attrs_before, List.rev acc, rewrite_underscore_apply expr) - | {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 | { pexp_desc = Pexp_fun @@ -202,25 +179,27 @@ let fun_expr expr = rhs = return_expr; arity; }; - pexp_attributes = []; + pexp_attributes = attrs; } when arity = None || n_fun = 0 -> - let parameter = - Parameter {attrs = []; lbl; default_expr; pat = pattern} - in - collect ~n_fun:(n_fun + 1) attrs_before (parameter :: acc) return_expr - (* If a fun has an attribute, then it stops here and makes currying. - i.e attributes outside of (...), uncurried `(.)` and `async` make currying *) - | {pexp_desc = Pexp_fun _} -> (attrs_before, List.rev acc, expr) - | expr when n_fun = 0 && Ast_uncurried.expr_is_uncurried_fun expr -> - let expr = Ast_uncurried.expr_extract_uncurried_fun expr in - collect ~n_fun attrs_before acc expr - | expr -> (attrs_before, List.rev acc, expr) + let parameter = Parameter {attrs; lbl; default_expr; pat = pattern} in + collect_params ~n_fun:(n_fun + 1) ~params:(parameter :: params) + return_expr + | _ -> (async, List.rev params, expr) in - match expr with - | {pexp_desc = Pexp_fun _ | Pexp_newtype _} -> - collect ~n_fun:0 expr.pexp_attributes [] {expr with pexp_attributes = []} - | _ -> collect ~n_fun:0 [] [] expr + (* Turns (type t, type u, type z) into "type t u z" *) + let rec collect_new_types acc return_expr = + match return_expr with + | {pexp_desc = Pexp_newtype (string_loc, return_expr)} -> + collect_new_types (string_loc :: acc) return_expr + | return_expr -> (List.rev acc, return_expr) + in + match expr_ with + | {pexp_desc = Pexp_newtype (string_loc, rest)} -> + let string_locs, return_expr = collect_new_types [string_loc] rest in + let param = NewTypes {attrs = []; locs = string_locs} in + collect_params ~n_fun:0 ~params:[param] return_expr + | _ -> collect_params ~n_fun:0 ~params:[] {expr_ with pexp_attributes = []} let process_braces_attr expr = match expr.pexp_attributes with diff --git a/compiler/syntax/src/res_parsetree_viewer.mli b/compiler/syntax/src/res_parsetree_viewer.mli index eb89bc8b53..a8e4ee2fcf 100644 --- a/compiler/syntax/src/res_parsetree_viewer.mli +++ b/compiler/syntax/src/res_parsetree_viewer.mli @@ -53,8 +53,7 @@ type fun_param_kind = | NewTypes of {attrs: Parsetree.attributes; locs: string Asttypes.loc list} val fun_expr : - Parsetree.expression -> - Parsetree.attributes * fun_param_kind list * Parsetree.expression + Parsetree.expression -> bool * fun_param_kind list * Parsetree.expression (* example: * `makeCoordinate({ diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml index cd2b9e99f9..15a85b6345 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -1980,7 +1980,7 @@ and print_value_binding ~state ~rec_flag (vb : Parsetree.value_binding) cmt_tbl }; pvb_expr = {pexp_desc = Pexp_newtype _} as expr; } -> ( - let _attrs, parameters, return_expr = ParsetreeViewer.fun_expr expr in + let _, parameters, return_expr = ParsetreeViewer.fun_expr expr in let abstract_type = match parameters with | [NewTypes {locs = vars}] -> @@ -2695,8 +2695,8 @@ 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 async, attrs = Ast_async.extract_async_attribute attrs_on_arrow in + let async, parameters, return_expr = ParsetreeViewer.fun_expr e in + let attrs_on_arrow = e.pexp_attributes in let return_expr, typ_constraint = match return_expr.pexp_desc with | Pexp_constraint (expr, typ) -> @@ -2759,7 +2759,7 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl = Doc.concat [Doc.text ": "; typ_doc] | _ -> Doc.nil in - let attrs = print_attributes ~state attrs cmt_tbl in + let attrs = print_attributes ~state attrs_on_arrow cmt_tbl in Doc.group (Doc.concat [ @@ -3436,8 +3436,8 @@ and print_expression ~state (e : Parsetree.expression) cmt_tbl = | _ -> expr_with_await and print_pexp_fun ~state ~in_callback e cmt_tbl = - let attrs_on_arrow, parameters, return_expr = ParsetreeViewer.fun_expr e in - let async, attrs = Ast_async.extract_async_attribute attrs_on_arrow in + let async, parameters, return_expr = ParsetreeViewer.fun_expr e in + let attrs_on_arrow = e.pexp_attributes in let return_expr, typ_constraint = match return_expr.pexp_desc with | Pexp_constraint (expr, typ) -> @@ -3503,7 +3503,7 @@ and print_pexp_fun ~state ~in_callback e cmt_tbl = in Doc.concat [ - print_attributes ~state attrs cmt_tbl; + print_attributes ~state attrs_on_arrow cmt_tbl; parameters_doc; typ_constraint_doc; Doc.text " =>"; diff --git a/tests/analysis_tests/tests-generic-jsx-transform/package-lock.json b/tests/analysis_tests/tests-generic-jsx-transform/package-lock.json index 3b8025fbcd..28180317c1 100644 --- a/tests/analysis_tests/tests-generic-jsx-transform/package-lock.json +++ b/tests/analysis_tests/tests-generic-jsx-transform/package-lock.json @@ -9,7 +9,8 @@ } }, "../../..": { - "version": "12.0.0-alpha.7", + "name": "rescript", + "version": "12.0.0-alpha.8", "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", "bin": { diff --git a/tests/analysis_tests/tests-incremental-typechecking/package-lock.json b/tests/analysis_tests/tests-incremental-typechecking/package-lock.json index b72b47f803..1f4807c3ef 100644 --- a/tests/analysis_tests/tests-incremental-typechecking/package-lock.json +++ b/tests/analysis_tests/tests-incremental-typechecking/package-lock.json @@ -9,7 +9,8 @@ } }, "../../..": { - "version": "12.0.0-alpha.7", + "name": "rescript", + "version": "12.0.0-alpha.8", "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", "bin": { diff --git a/tests/analysis_tests/tests-reanalyze/deadcode/package-lock.json b/tests/analysis_tests/tests-reanalyze/deadcode/package-lock.json index f0d7a7aa63..604c1602a7 100644 --- a/tests/analysis_tests/tests-reanalyze/deadcode/package-lock.json +++ b/tests/analysis_tests/tests-reanalyze/deadcode/package-lock.json @@ -15,7 +15,8 @@ } }, "../../../..": { - "version": "12.0.0-alpha.7", + "name": "rescript", + "version": "12.0.0-alpha.8", "dev": true, "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", diff --git a/tests/analysis_tests/tests-reanalyze/termination/package-lock.json b/tests/analysis_tests/tests-reanalyze/termination/package-lock.json index 55367e22a2..fd0cd95e7d 100644 --- a/tests/analysis_tests/tests-reanalyze/termination/package-lock.json +++ b/tests/analysis_tests/tests-reanalyze/termination/package-lock.json @@ -12,7 +12,8 @@ } }, "../../../..": { - "version": "12.0.0-alpha.7", + "name": "rescript", + "version": "12.0.0-alpha.8", "dev": true, "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", diff --git a/tests/analysis_tests/tests/package-lock.json b/tests/analysis_tests/tests/package-lock.json index d6864a9574..1f0d8fa0ca 100644 --- a/tests/analysis_tests/tests/package-lock.json +++ b/tests/analysis_tests/tests/package-lock.json @@ -33,6 +33,7 @@ } }, "../../..": { + "name": "rescript", "version": "12.0.0-alpha.8", "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", 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 bfa4292396..532bd33f9e 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 @@ -34,15 +34,16 @@ 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 [arity:1]() -> fun (type b) -> fun (type c) -> fun [arity:1]x -> 3) - [@res.async ][@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) + 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 ])) + 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]() -> 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/parsing/grammar/expressions/expected/locallyAbstractTypes.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/locallyAbstractTypes.res.txt index 21ac8611c1..58f56be174 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/locallyAbstractTypes.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/locallyAbstractTypes.res.txt @@ -1,16 +1,16 @@ let f (type t) [arity:1](xs : t list) = () -let f (type t) [arity:2](xs : t list) (type s) (ys : s list) = () +let f (type t) (type s) [arity:2](xs : t list) (ys : s list) = () let f (type t) (type u) (type v) [arity:1](xs : (t * u * v) list) = () -let f (type t) (type u) (type v) [arity:2](xs : (t * u * v) list) (type s) - (type w) (type z) (ys : (s * w * z) list) = () -let f = ((fun (type t) -> fun (type u) -> fun (type v) -> - fun [arity:2](xs : (t * u * v) list) -> ((fun (type s) -> fun (type w) -> - fun (type z) -> fun (ys : (s * w * z) list) -> ())[@attr2 ])) - [@attr ]) -let f = ((fun (type t) -> ((fun (type s) -> - fun [arity:2](xs : (t * s) list) -> ((fun (type u) -> ((fun (type v) -> fun - (type w) -> fun (ys : (u * v * w) list) -> ())[@attr ]))[@attr ])) - [@attr ]))[@attr ]) +let f (type t) (type u) (type v) (type s) (type w) (type z) + [arity:2](xs : (t * u * v) list) (ys : (s * w * z) list) = () +let f = ((fun (type t) -> fun (type u) -> fun (type v) -> fun (type s) -> fun + (type w) -> fun (type z) -> + fun [arity:2](xs : (t * u * v) list) -> fun (ys : (s * w * z) list) -> ()) + [@attr ][@attr2 ]) +let f = ((fun (type t) -> fun (type s) -> fun (type u) -> fun (type v) -> fun + (type w) -> + fun [arity:2](xs : (t * s) list) -> fun (ys : (u * v * w) list) -> ()) + [@attr ][@attr ][@attr ][@attr ]) let cancel_and_collect_callbacks : 'a 'u 'c . packed_callbacks list -> 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 5b5cbccd83..7d4a0b3811 100644 --- a/tests/syntax_tests/data/printer/comments/expected/expr.res.txt +++ b/tests/syntax_tests/data/printer/comments/expected/expr.res.txt @@ -227,8 +227,11 @@ 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 */ s, + /* c0 */ m1 /* c1 */, + /* c-2 */ /* c-1 */ /* c2 */ m2 /* c3 */, +) => () f( // a 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 5ba8123497..e97ff990e0 100644 --- a/tests/syntax_tests/data/printer/expr/expected/newtype.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/newtype.res.txt @@ -1,14 +1,12 @@ 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 s, xs: list, ys: list) => () +let f = @attr @attr2 (type t s, xs: list, 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 = @attr -(type t, @attr type s, xs: list<(t, s)>) => - @attr (type u, @attr type v w, ys: list<(u, v, w)>) => () +let f = (type t u v s w z, xs: list<(t, u, v)>, ys: list<(s, w, z)>) => () +let f = @attr @attr2 (type t u v s w z, xs: list<(t, u, v)>, ys: list<(s, w, z)>) => () +let f = @attr @attr @attr @attr (type t s u v w, xs: list<(t, s)>, ys: list<(u, v, w)>) => () let mk_formatting_gen: type a b c d e f. formatting_gen => Parsetree.expression = diff --git a/tests/tools_tests/package-lock.json b/tests/tools_tests/package-lock.json index 13289a79ee..8118ee2f99 100644 --- a/tests/tools_tests/package-lock.json +++ b/tests/tools_tests/package-lock.json @@ -14,7 +14,8 @@ } }, "../..": { - "version": "12.0.0-alpha.7", + "name": "rescript", + "version": "12.0.0-alpha.8", "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", "bin": {