diff --git a/CHANGELOG.md b/CHANGELOG.md index c84d8a9cf8..2ed32b8684 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - 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 - AST cleanup: Remove `@res.async` attribute from the internal representation, and add a flag to untyped and typed ASTs instead. https://github.com/rescript-lang/rescript/pull/7234 +- AST cleanup: Remove `@res.partial` attribute from the internal representation, and add a flag to untyped and typed ASTs instead. https://github.com/rescript-lang/rescript/pull/7238 https://github.com/rescript-lang/rescript/pull/7240 # 12.0.0-alpha.7 diff --git a/analysis/src/CompletionFrontEnd.ml b/analysis/src/CompletionFrontEnd.ml index c9acc4955e..aa9c1ba80f 100644 --- a/analysis/src/CompletionFrontEnd.ml +++ b/analysis/src/CompletionFrontEnd.ml @@ -262,12 +262,14 @@ let rec exprToContextPathInner (e : Parsetree.expression) = pexp_loc; pexp_attributes; }; - args = [(_, lhs); (_, {pexp_desc = Pexp_apply {funct = d; args}})]; + args = + [(_, lhs); (_, {pexp_desc = Pexp_apply {funct = d; args; partial}})]; } -> (* Transform away pipe with apply call *) exprToContextPath { - pexp_desc = Pexp_apply {funct = d; args = (Nolabel, lhs) :: args}; + pexp_desc = + Pexp_apply {funct = d; args = (Nolabel, lhs) :: args; partial}; pexp_loc; pexp_attributes; } @@ -278,6 +280,7 @@ let rec exprToContextPathInner (e : Parsetree.expression) = [ (_, lhs); (_, {pexp_desc = Pexp_ident id; pexp_loc; pexp_attributes}); ]; + partial; } -> (* Transform away pipe with identifier *) exprToContextPath @@ -287,6 +290,7 @@ let rec exprToContextPathInner (e : Parsetree.expression) = { funct = {pexp_desc = Pexp_ident id; pexp_loc; pexp_attributes}; args = [(Nolabel, lhs)]; + partial; }; pexp_loc; pexp_attributes; diff --git a/compiler/frontend/ast_compatible.ml b/compiler/frontend/ast_compatible.ml index 707d0e9fdb..d4f27fa998 100644 --- a/compiler/frontend/ast_compatible.ml +++ b/compiler/frontend/ast_compatible.ml @@ -40,14 +40,19 @@ let apply_simple ?(loc = default_loc) ?(attrs = []) (fn : expression) pexp_attributes = attrs; pexp_desc = Pexp_apply - {funct = fn; args = Ext_list.map args (fun x -> (Asttypes.Nolabel, x))}; + { + funct = fn; + args = Ext_list.map args (fun x -> (Asttypes.Nolabel, x)); + partial = false; + }; } let app1 ?(loc = default_loc) ?(attrs = []) fn arg1 : expression = { pexp_loc = loc; pexp_attributes = attrs; - pexp_desc = Pexp_apply {funct = fn; args = [(Nolabel, arg1)]}; + pexp_desc = + Pexp_apply {funct = fn; args = [(Nolabel, arg1)]; partial = false}; } let app2 ?(loc = default_loc) ?(attrs = []) fn arg1 arg2 : expression = @@ -55,7 +60,8 @@ let app2 ?(loc = default_loc) ?(attrs = []) fn arg1 arg2 : expression = pexp_loc = loc; pexp_attributes = attrs; pexp_desc = - Pexp_apply {funct = fn; args = [(Nolabel, arg1); (Nolabel, arg2)]}; + Pexp_apply + {funct = fn; args = [(Nolabel, arg1); (Nolabel, arg2)]; partial = false}; } let app3 ?(loc = default_loc) ?(attrs = []) fn arg1 arg2 arg3 : expression = @@ -64,7 +70,11 @@ let app3 ?(loc = default_loc) ?(attrs = []) fn arg1 arg2 arg3 : expression = pexp_attributes = attrs; pexp_desc = Pexp_apply - {funct = fn; args = [(Nolabel, arg1); (Nolabel, arg2); (Nolabel, arg3)]}; + { + funct = fn; + args = [(Nolabel, arg1); (Nolabel, arg2); (Nolabel, arg3)]; + partial = false; + }; } let fun_ ?(loc = default_loc) ?(attrs = []) ?(async = false) ~arity pat exp = @@ -108,6 +118,7 @@ let apply_labels ?(loc = default_loc) ?(attrs = []) fn { funct = fn; args = Ext_list.map args (fun (l, a) -> (Asttypes.Labelled l, a)); + partial = false; }; } diff --git a/compiler/frontend/ast_exp_apply.ml b/compiler/frontend/ast_exp_apply.ml index 66202b207f..2763dc4bae 100644 --- a/compiler/frontend/ast_exp_apply.ml +++ b/compiler/frontend/ast_exp_apply.ml @@ -88,10 +88,11 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) : exp = {f with pexp_desc = Pexp_variant (label, Some a); pexp_loc = e.pexp_loc} | Pexp_construct (ctor, None) -> {f with pexp_desc = Pexp_construct (ctor, Some a); pexp_loc = e.pexp_loc} - | Pexp_apply {funct = fn1; args} -> + | Pexp_apply {funct = fn1; args; partial} -> Bs_ast_invariant.warn_discarded_unused_attributes fn1.pexp_attributes; { - pexp_desc = Pexp_apply {funct = fn1; args = (Nolabel, a) :: args}; + pexp_desc = + Pexp_apply {funct = fn1; args = (Nolabel, a) :: args; partial}; pexp_loc = e.pexp_loc; pexp_attributes = e.pexp_attributes @ f.pexp_attributes; } @@ -116,6 +117,7 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) : exp = { funct = fn; args = (Nolabel, bounded_obj_arg) :: args; + partial = false; }; pexp_attributes = []; pexp_loc = fn.pexp_loc; diff --git a/compiler/frontend/ast_uncurry_gen.ml b/compiler/frontend/ast_uncurry_gen.ml index 41d2b2068d..70e4e2d550 100644 --- a/compiler/frontend/ast_uncurry_gen.ml +++ b/compiler/frontend/ast_uncurry_gen.ml @@ -74,4 +74,5 @@ let to_method_callback loc (self : Bs_ast_mapper.mapper) label } [Typ.any ~loc ()]) ); ]; + partial = false; } diff --git a/compiler/frontend/bs_ast_mapper.ml b/compiler/frontend/bs_ast_mapper.ml index 992e552cac..992edc60c6 100644 --- a/compiler/frontend/bs_ast_mapper.ml +++ b/compiler/frontend/bs_ast_mapper.ml @@ -320,8 +320,9 @@ module E = struct fun_ ~loc ~attrs ~arity ~async lab (map_opt (sub.expr sub) def) (sub.pat sub p) (sub.expr sub e) - | Pexp_apply {funct = e; args = l} -> - apply ~loc ~attrs (sub.expr sub e) (List.map (map_snd (sub.expr sub)) l) + | Pexp_apply {funct = e; args = l; partial} -> + apply ~loc ~attrs ~partial (sub.expr sub e) + (List.map (map_snd (sub.expr sub)) l) | Pexp_match (e, pel) -> match_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) | Pexp_try (e, pel) -> try_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) diff --git a/compiler/ml/ast_helper.ml b/compiler/ml/ast_helper.ml index 7af27c9656..096ba9264a 100644 --- a/compiler/ml/ast_helper.ml +++ b/compiler/ml/ast_helper.ml @@ -154,7 +154,8 @@ module Exp = struct let fun_ ?loc ?attrs ?(async = false) ~arity a b c d = mk ?loc ?attrs (Pexp_fun {arg_label = a; default = b; lhs = c; rhs = d; arity; async}) - let apply ?loc ?attrs funct args = mk ?loc ?attrs (Pexp_apply {funct; args}) + let apply ?loc ?attrs ?(partial = false) funct args = + mk ?loc ?attrs (Pexp_apply {funct; args; partial}) let match_ ?loc ?attrs a b = mk ?loc ?attrs (Pexp_match (a, b)) let try_ ?loc ?attrs a b = mk ?loc ?attrs (Pexp_try (a, b)) let tuple ?loc ?attrs a = mk ?loc ?attrs (Pexp_tuple a) diff --git a/compiler/ml/ast_helper.mli b/compiler/ml/ast_helper.mli index 99b5018583..5133c6e2f1 100644 --- a/compiler/ml/ast_helper.mli +++ b/compiler/ml/ast_helper.mli @@ -148,6 +148,7 @@ module Exp : sig val apply : ?loc:loc -> ?attrs:attrs -> + ?partial:bool -> expression -> (arg_label * expression) list -> expression diff --git a/compiler/ml/ast_mapper.ml b/compiler/ml/ast_mapper.ml index 69c3586036..a19152e37c 100644 --- a/compiler/ml/ast_mapper.ml +++ b/compiler/ml/ast_mapper.ml @@ -283,8 +283,9 @@ module E = struct fun_ ~loc ~attrs ~arity ~async lab (map_opt (sub.expr sub) def) (sub.pat sub p) (sub.expr sub e) - | Pexp_apply {funct = e; args = l} -> - apply ~loc ~attrs (sub.expr sub e) (List.map (map_snd (sub.expr sub)) l) + | Pexp_apply {funct = e; args = l; partial} -> + apply ~loc ~attrs ~partial (sub.expr sub e) + (List.map (map_snd (sub.expr sub)) l) | Pexp_match (e, pel) -> match_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) | Pexp_try (e, pel) -> try_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) diff --git a/compiler/ml/ast_mapper_from0.ml b/compiler/ml/ast_mapper_from0.ml index 345354d616..88b67b5a20 100644 --- a/compiler/ml/ast_mapper_from0.ml +++ b/compiler/ml/ast_mapper_from0.ml @@ -310,7 +310,18 @@ module E = struct (sub.pat sub p) (sub.expr sub e) | Pexp_function _ -> assert false | Pexp_apply (e, l) -> - apply ~loc ~attrs (sub.expr sub e) (List.map (map_snd (sub.expr sub)) l) + let process_partial_app_attribute attrs = + let rec process partial_app acc attrs = + match attrs with + | [] -> (partial_app, List.rev acc) + | ({Location.txt = "res.partial"}, _) :: rest -> process true acc rest + | attr :: rest -> process partial_app (attr :: acc) rest + in + process false [] attrs + in + let partial, attrs = process_partial_app_attribute attrs in + apply ~loc ~attrs ~partial (sub.expr sub e) + (List.map (map_snd (sub.expr sub)) l) | Pexp_match (e, pel) -> match_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) | Pexp_try (e, pel) -> try_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) diff --git a/compiler/ml/ast_mapper_to0.ml b/compiler/ml/ast_mapper_to0.ml index 70a68a98d2..2a159a07d6 100644 --- a/compiler/ml/ast_mapper_to0.ml +++ b/compiler/ml/ast_mapper_to0.ml @@ -325,7 +325,11 @@ module E = struct ~attrs:(arity_to_attributes arity) (Location.mkloc (Longident.Lident "Function$") e.pexp_loc) (Some e)) - | Pexp_apply {funct = e; args = l} -> + | Pexp_apply {funct = e; args = l; partial} -> + let attrs = + if partial then (Location.mknoloc "res.partial", Pt.PStr []) :: attrs + else [] + in apply ~loc ~attrs (sub.expr sub e) (List.map (map_snd (sub.expr sub)) l) | Pexp_match (e, pel) -> match_ ~loc ~attrs (sub.expr sub e) (sub.cases sub pel) diff --git a/compiler/ml/parsetree.ml b/compiler/ml/parsetree.ml index ac3362783e..26c6ca9da7 100644 --- a/compiler/ml/parsetree.ml +++ b/compiler/ml/parsetree.ml @@ -242,7 +242,11 @@ and expression_desc = - "fun P1 P2 .. Pn -> E1" is represented as nested Pexp_fun. - "let f P = E" is represented using Pexp_fun. *) - | Pexp_apply of {funct: expression; args: (arg_label * expression) list} + | Pexp_apply of { + funct: expression; + args: (arg_label * expression) list; + partial: bool; + } (* E0 ~l1:E1 ... ~ln:En li can be empty (non labeled argument) or start with '?' (optional argument). diff --git a/compiler/ml/pprintast.ml b/compiler/ml/pprintast.ml index cb746ccb41..7b089e33ec 100644 --- a/compiler/ml/pprintast.ml +++ b/compiler/ml/pprintast.ml @@ -631,7 +631,7 @@ and expression ctxt f x = (* rec_flag rf *) pp f "@[<2>%a in@;<1 -2>%a@]" (bindings reset_ctxt) (rf, l) (expression ctxt) e - | Pexp_apply {funct = e; args = l} -> ( + | Pexp_apply {funct = e; args = l; partial} -> ( if not (sugar_expr ctxt f x) then match view_fixity_of_exp e with | `Infix s -> ( @@ -667,14 +667,15 @@ and expression ctxt f x = (list (label_x_expression_param ctxt)) l) | _ -> - pp f "@[%a@]" + let partial_str = if partial then " ..." else "" in + pp f "@[%a%s@]" (fun f (e, l) -> pp f "%a@ %a" (expression2 ctxt) e (list (label_x_expression_param reset_ctxt)) l) (* reset here only because [function,match,try,sequence] are lower priority *) - (e, l)) + (e, l) partial_str) | Pexp_construct (li, Some eo) when not (is_simple_construct (view_expr x)) -> ( (* Not efficient FIXME*) diff --git a/compiler/ml/printast.ml b/compiler/ml/printast.ml index 5a1e245637..338db444a5 100644 --- a/compiler/ml/printast.ml +++ b/compiler/ml/printast.ml @@ -250,8 +250,9 @@ and expression i ppf x = option i expression ppf eo; pattern i ppf p; expression i ppf e - | Pexp_apply {funct = e; args = l} -> + | Pexp_apply {funct = e; args = l; partial} -> line i ppf "Pexp_apply\n"; + if partial then line i ppf "partial\n"; expression i ppf e; list i label_x_expression ppf l | Pexp_match (e, l) -> diff --git a/compiler/ml/printtyped.ml b/compiler/ml/printtyped.ml index c6db39060d..9196c2534d 100644 --- a/compiler/ml/printtyped.ml +++ b/compiler/ml/printtyped.ml @@ -295,7 +295,8 @@ and expression i ppf x = line i ppf "%a" Ident.print param; arg_label i ppf p; case i ppf case_ - | Texp_apply {funct = e; args = l} -> + | Texp_apply {funct = e; args = l; partial} -> + if partial then line i ppf "partial\n"; line i ppf "Texp_apply\n"; expression i ppf e; list i label_x_expression ppf l diff --git a/compiler/ml/tast_mapper.ml b/compiler/ml/tast_mapper.ml index 22baed190d..bc367a85c1 100644 --- a/compiler/ml/tast_mapper.ml +++ b/compiler/ml/tast_mapper.ml @@ -202,11 +202,12 @@ let expr sub x = | Texp_function {arg_label; arity; param; case; partial; async} -> Texp_function {arg_label; arity; param; case = sub.case sub case; partial; async} - | Texp_apply {funct = exp; args = list} -> + | Texp_apply {funct = exp; args = list; partial} -> Texp_apply { funct = sub.expr sub exp; args = List.map (tuple2 id (opt (sub.expr sub))) list; + partial; } | Texp_match (exp, cases, exn_cases, p) -> Texp_match diff --git a/compiler/ml/translcore.ml b/compiler/ml/translcore.ml index 92a6f50e5a..df20bb6ca0 100644 --- a/compiler/ml/translcore.ml +++ b/compiler/ml/translcore.ml @@ -760,17 +760,14 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda = | Plazyforce, [a] -> wrap (Matching.inline_lazy_force a e.exp_loc) | Plazyforce, _ -> assert false | _ -> wrap (Lprim (prim, argl, e.exp_loc)))) - | Texp_apply {funct; args = oargs} -> + | Texp_apply {funct; args = oargs; partial} -> let inlined, funct = Translattribute.get_and_remove_inlined_attribute funct in let uncurried_partial_application = (* In case of partial application foo(args, ...) when some args are missing, get the arity *) - let uncurried_partial_app = - Ext_list.exists e.exp_attributes (fun ({txt}, _) -> txt = "res.partial") - in - if uncurried_partial_app then + if partial then let arity_opt = Ctype.get_arity funct.exp_env funct.exp_type in match arity_opt with | Some arity -> diff --git a/compiler/ml/typecore.ml b/compiler/ml/typecore.ml index fa5ad4b639..0b395355f6 100644 --- a/compiler/ml/typecore.ml +++ b/compiler/ml/typecore.ml @@ -2420,7 +2420,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp type_function ?in_function ~arity ~async loc sexp.pexp_attributes env ty_expected l [Ast_helper.Exp.case spat sbody] - | Pexp_apply {funct = sfunct; args = sargs} -> + | Pexp_apply {funct = sfunct; args = sargs; partial} -> assert (sargs <> []); begin_def (); (* one more level for non-returning functions *) @@ -2429,11 +2429,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp end_def (); wrap_trace_gadt_instances env (lower_args env []) ty; begin_def (); - let total_app = - not - @@ Ext_list.exists sexp.pexp_attributes (fun ({txt}, _) -> - txt = "res.partial") - in + let total_app = not partial in let type_clash_context = type_clash_context_from_function sexp sfunct in let args, ty_res, fully_applied = match translate_unified_ops env funct sargs with @@ -2446,7 +2442,7 @@ and type_expect_ ?type_clash_context ?in_function ?(recarg = Rejected) env sexp let mk_apply funct args = rue { - exp_desc = Texp_apply {funct; args}; + exp_desc = Texp_apply {funct; args; partial}; exp_loc = loc; exp_extra = []; exp_type = ty_res; diff --git a/compiler/ml/typedtree.ml b/compiler/ml/typedtree.ml index 89df6ea32e..d38c30737e 100644 --- a/compiler/ml/typedtree.ml +++ b/compiler/ml/typedtree.ml @@ -87,6 +87,7 @@ and expression_desc = | Texp_apply of { funct: expression; args: (arg_label * expression option) list; + partial: bool; } | Texp_match of expression * case list * case list * partial | Texp_try of expression * case list diff --git a/compiler/ml/typedtree.mli b/compiler/ml/typedtree.mli index b13b529b9d..2d10aecc20 100644 --- a/compiler/ml/typedtree.mli +++ b/compiler/ml/typedtree.mli @@ -151,6 +151,7 @@ and expression_desc = | Texp_apply of { funct: expression; args: (arg_label * expression option) list; + partial: bool; } (** E0 ~l1:E1 ... ~ln:En diff --git a/compiler/syntax/src/res_core.ml b/compiler/syntax/src/res_core.ml index 3d7e0e1e72..313b1c7d2e 100644 --- a/compiler/syntax/src/res_core.ml +++ b/compiler/syntax/src/res_core.ml @@ -2221,11 +2221,12 @@ and parse_binary_expr ?(context = OrdinaryExpr) ?a p prec = let loc = mk_loc a.Parsetree.pexp_loc.loc_start b.pexp_loc.loc_end in let expr = match (token, b.pexp_desc) with - | BarGreater, Pexp_apply {funct = fun_expr; args} -> + | BarGreater, Pexp_apply {funct = fun_expr; args; partial} -> { b with pexp_desc = - Pexp_apply {funct = fun_expr; args = args @ [(Nolabel, a)]}; + Pexp_apply + {funct = fun_expr; args = args @ [(Nolabel, a)]; partial}; } | BarGreater, _ -> Ast_helper.Exp.apply ~loc b [(Nolabel, a)] | _ -> @@ -3682,11 +3683,7 @@ and parse_call_expr p fun_expr = parse_comma_delimited_region ~grammar:Grammar.ArgumentList ~closing:Rparen ~f:parse_argument p in - let res_partial_attr = - let loc = mk_loc start_pos p.prev_end_pos in - (Location.mkloc "res.partial" loc, Parsetree.PStr []) - in - let is_partial = + let partial = match p.token with | DotDotDot when args <> [] -> Parser.next p; @@ -3708,45 +3705,6 @@ and parse_call_expr p fun_expr = None; }; ] - | [ - { - label = Nolabel; - expr = - { - pexp_desc = Pexp_construct ({txt = Longident.Lident "()"}, None); - pexp_loc = loc; - pexp_attributes = []; - } as expr; - }; - ] - when (not loc.loc_ghost) && p.mode = ParseForTypeChecker && not is_partial - -> - (* Since there is no syntax space for arity zero vs arity one, - * we expand - * `fn(. ())` into - * `fn(. {let __res_unit = (); __res_unit})` - * when the parsetree is intended for type checking - * - * Note: - * `fn(.)` is treated as zero arity application. - * The invisible unit expression here has loc_ghost === true - * - * Related: https://github.com/rescript-lang/syntax/issues/138 - *) - [ - { - label = Nolabel; - expr = - Ast_helper.Exp.let_ Asttypes.Nonrecursive - [ - Ast_helper.Vb.mk - (Ast_helper.Pat.var (Location.mknoloc "__res_unit")) - expr; - ] - (Ast_helper.Exp.ident - (Location.mknoloc (Longident.Lident "__res_unit"))); - }; - ] | args -> args in let loc = {fun_expr.pexp_loc with loc_end = p.prev_end_pos} in @@ -3761,10 +3719,7 @@ and parse_call_expr p fun_expr = let apply = Ext_list.fold_left args fun_expr (fun call_body args -> let args, wrap = process_underscore_application args in - let exp = - let attrs = if is_partial then [res_partial_attr] else [] in - Ast_helper.Exp.apply ~loc ~attrs call_body args - in + let exp = Ast_helper.Exp.apply ~loc ~partial call_body args in wrap exp) in diff --git a/compiler/syntax/src/res_parsetree_viewer.ml b/compiler/syntax/src/res_parsetree_viewer.ml index ea4d4c3354..8185bea0a2 100644 --- a/compiler/syntax/src/res_parsetree_viewer.ml +++ b/compiler/syntax/src/res_parsetree_viewer.ml @@ -70,15 +70,6 @@ let functor_type modtype = in process [] modtype -let process_partial_app_attribute attrs = - let rec process partial_app acc attrs = - match attrs with - | [] -> (partial_app, List.rev acc) - | ({Location.txt = "res.partial"}, _) :: rest -> process true acc rest - | attr :: rest -> process partial_app (attr :: acc) rest - in - process false [] attrs - let has_await_attribute attrs = List.exists (function @@ -146,7 +137,11 @@ let rewrite_underscore_apply expr = | arg -> arg) args in - {e with pexp_desc = Pexp_apply {funct = call_expr; args = new_args}} + { + e with + pexp_desc = + Pexp_apply {funct = call_expr; args = new_args; partial = false}; + } | _ -> expr type fun_param_kind = diff --git a/compiler/syntax/src/res_parsetree_viewer.mli b/compiler/syntax/src/res_parsetree_viewer.mli index 30225de6a1..6ea777726c 100644 --- a/compiler/syntax/src/res_parsetree_viewer.mli +++ b/compiler/syntax/src/res_parsetree_viewer.mli @@ -14,9 +14,6 @@ val functor_type : list * Parsetree.module_type -val process_partial_app_attribute : - Parsetree.attributes -> bool * Parsetree.attributes - 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 d87f036bf8..ed6f33b14a 100644 --- a/compiler/syntax/src/res_printer.ml +++ b/compiler/syntax/src/res_printer.ml @@ -4264,14 +4264,13 @@ and print_pexp_apply ~state expr cmt_tbl = | Pexp_apply {funct = {pexp_desc = Pexp_ident lident}; args} when ParsetreeViewer.is_jsx_expression expr -> print_jsx_expression ~state lident args cmt_tbl - | Pexp_apply {funct = call_expr; args} -> + | Pexp_apply {funct = call_expr; args; partial} -> let args = List.map (fun (lbl, arg) -> (lbl, ParsetreeViewer.rewrite_underscore_apply arg)) args in let attrs = expr.pexp_attributes in - let partial, attrs = ParsetreeViewer.process_partial_app_attribute attrs in let args = if partial then let dummy = Ast_helper.Exp.constant ~attrs (Ast_helper.Const.int 0) in diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/apply.res b/tests/syntax_tests/data/parsing/grammar/expressions/apply.res index 260a5fdb8b..a22f887fbe 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/apply.res +++ b/tests/syntax_tests/data/parsing/grammar/expressions/apply.res @@ -9,3 +9,5 @@ List.reduce((acc, curr) => acc + curr, 0, myList) let unitUncurried = apply(.) call(~a: int) + +call_partial(3, ...) diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/apply.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/apply.res.txt index d3a2e0fdc1..ffe47af868 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/apply.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/apply.res.txt @@ -5,4 +5,5 @@ ;;List.map (fun [arity:1]x -> x + 1) myList ;;List.reduce (fun [arity:2]acc -> fun curr -> acc + curr) 0 myList let unitUncurried = apply () -;;call ~a:(((((a)[@res.namedArgLoc ]) : int))[@res.namedArgLoc ]) \ No newline at end of file +;;call ~a:(((((a)[@res.namedArgLoc ]) : int))[@res.namedArgLoc ]) +;;call_partial 3 ... \ No newline at end of file diff --git a/tests/syntax_tests/data/parsing/grammar/expressions/expected/argument.res.txt b/tests/syntax_tests/data/parsing/grammar/expressions/expected/argument.res.txt index d2820b878e..3b1fe1a857 100644 --- a/tests/syntax_tests/data/parsing/grammar/expressions/expected/argument.res.txt +++ b/tests/syntax_tests/data/parsing/grammar/expressions/expected/argument.res.txt @@ -1,5 +1,4 @@ -let foo [arity:1]~a:((a)[@res.namedArgLoc ]) = - (a (let __res_unit = () in __res_unit)) +. 1. +let foo [arity:1]~a:((a)[@res.namedArgLoc ]) = (a ()) +. 1. let a [arity:1]() = 2 let bar = foo ~a:((a)[@res.namedArgLoc ]) let comparisonResult = @@ -9,4 +8,4 @@ let comparisonResult = (elementProps ~onClick:((fun [arity:1]_ -> Js.log {js|hello world|js}) [@res.namedArgLoc ])) ;;resolve () -;;resolve (let __res_unit = () in __res_unit) \ No newline at end of file +;;resolve () \ No newline at end of file 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 1c9db31945..f2127546d8 100644 --- a/tests/syntax_tests/data/printer/expr/expected/UncurriedByDefault.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/UncurriedByDefault.res.txt @@ -170,10 +170,9 @@ let fn = ( provikingMultilineFormattingaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa } -let partial = - fn( - ~hello=1, - ~moreGoesHere=1, - ~provikingMultilineFormattingaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1, - ... - ) +let partial = fn( + ~hello=1, + ~moreGoesHere=1, + ~provikingMultilineFormattingaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=1, + ... +) diff --git a/tests/syntax_tests/data/printer/expr/expected/apply.res.txt b/tests/syntax_tests/data/printer/expr/expected/apply.res.txt index f37f83f248..abe9fa030c 100644 --- a/tests/syntax_tests/data/printer/expr/expected/apply.res.txt +++ b/tests/syntax_tests/data/printer/expr/expected/apply.res.txt @@ -100,40 +100,34 @@ let g = f( c, ) -let g = - f( - a => - LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx(a), - b, - c, - ... - ) - -let g = - f( - a => - LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx(a), - b, - c => - LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx( - d, - ... - ), - ... - ) - -let g = - f( - a => - LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx( - a, - ... - ), - b, - c => - LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx(d), - ... - ) +let g = f( + a => LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx(a), + b, + c, + ... +) + +let g = f( + a => LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx(a), + b, + c => + LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx( + d, + ... + ), + ... +) + +let g = f( + a => + LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx( + a, + ... + ), + b, + c => LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx(d), + ... +) let g = f( a => LongModuleName.functionWithAlongNameThatWrapsTheEditorToTheNextLinexxxxxxxxxxxxxxxxxxxxxx(a), diff --git a/tests/tests/src/arity_deopt.mjs b/tests/tests/src/arity_deopt.mjs index 0ace475fa5..f59ec56b74 100644 --- a/tests/tests/src/arity_deopt.mjs +++ b/tests/tests/src/arity_deopt.mjs @@ -41,13 +41,13 @@ function f3(x) { return (y, z) => (x + y | 0) + z | 0; } -eq("File \"arity_deopt.res\", line 50, characters 6-13", 6, 6); +eq("File \"arity_deopt.res\", line 50, characters 5-12", 6, 6); -eq("File \"arity_deopt.res\", line 51, characters 6-13", 6, 6); +eq("File \"arity_deopt.res\", line 51, characters 5-12", 6, 6); -eq("File \"arity_deopt.res\", line 52, characters 6-13", 6, 6); +eq("File \"arity_deopt.res\", line 52, characters 5-12", 6, 6); -eq("File \"arity_deopt.res\", line 53, characters 6-13", 6, 6); +eq("File \"arity_deopt.res\", line 53, characters 5-12", 6, 6); Mt.from_pair_suites("Arity_deopt", suites.contents); diff --git a/tests/tests/src/arity_deopt.res b/tests/tests/src/arity_deopt.res index d8376b2a5a..41123e6615 100644 --- a/tests/tests/src/arity_deopt.res +++ b/tests/tests/src/arity_deopt.res @@ -47,9 +47,9 @@ let f3 = x => { So the best is never shrink functons which could change arity */ let () = { - (eq(__LOC__, 6, ...))(f0(1, 2, 3)) - (eq(__LOC__, 6, ...))(f1(1)(2, 3)) - (eq(__LOC__, 6, ...))(f2(1, 2)(3)) - (eq(__LOC__, 6, ...))(f3(1)(2, 3)) + eq(__LOC__, 6, ...)(f0(1, 2, 3)) + eq(__LOC__, 6, ...)(f1(1)(2, 3)) + eq(__LOC__, 6, ...)(f2(1, 2)(3)) + eq(__LOC__, 6, ...)(f3(1)(2, 3)) } let () = Mt.from_pair_suites(__MODULE__, suites.contents) diff --git a/tests/tests/src/bs_mutable_set_test.mjs b/tests/tests/src/bs_mutable_set_test.mjs index 8a2f59ddde..f5bc04852e 100644 --- a/tests/tests/src/bs_mutable_set_test.mjs +++ b/tests/tests/src/bs_mutable_set_test.mjs @@ -284,7 +284,7 @@ for (let i$2 = 0; i$2 <= 100000; ++i$2) { Belt_MutableSetInt.checkInvariantInternal(v$1); -b("File \"bs_mutable_set_test.res\", line 168, characters 5-12", Belt_Range.every(0, 100000, i => Belt_MutableSetInt.has(v$1, i))); +b("File \"bs_mutable_set_test.res\", line 168, characters 4-11", Belt_Range.every(0, 100000, i => Belt_MutableSetInt.has(v$1, i))); eq("File \"bs_mutable_set_test.res\", line 169, characters 5-12", Belt_MutableSetInt.size(v$1), 100001); diff --git a/tests/tests/src/bs_mutable_set_test.res b/tests/tests/src/bs_mutable_set_test.res index 65b7ab93a5..dc31d66fc4 100644 --- a/tests/tests/src/bs_mutable_set_test.res +++ b/tests/tests/src/bs_mutable_set_test.res @@ -165,7 +165,7 @@ let () = { N.add(v, i) } N.checkInvariantInternal(v) - (b(__LOC__, ...))(R.every(0, 1_00_000, i => N.has(v, i))) + b(__LOC__, ...)(R.every(0, 1_00_000, i => N.has(v, i))) eq(__LOC__, N.size(v), 1_00_001) } diff --git a/tests/tests/src/gpr_2614_test.res b/tests/tests/src/gpr_2614_test.res index 9b1c8bddbc..ee011e2fa6 100644 --- a/tests/tests/src/gpr_2614_test.res +++ b/tests/tests/src/gpr_2614_test.res @@ -36,8 +36,7 @@ external a : ?low:int -> hi:int -> a low: a -> int option [@@return undefined_to_opt] lowSet : a -> int -> unit */ -let h0 = - a(~hi=2, ~low="x", ...) +let h0 = a(~hi=2, ~low="x", ...) let h1 = a(~hi=2, ~low="x", ()) diff --git a/tests/tests/src/map_find_test.res b/tests/tests/src/map_find_test.res index e4c3c828d7..3e12d81275 100644 --- a/tests/tests/src/map_find_test.res +++ b/tests/tests/src/map_find_test.res @@ -19,7 +19,7 @@ include ( ) => acc->SMap.set(k, v)) @val("console.log") external log: 'a => unit = "" - (Mt.from_pair_suites(__MODULE__, ...))(list{ + Mt.from_pair_suites(__MODULE__, ...)(list{ ("int", _ => Eq(IntMap.get(m, 10), Some('a'))), ("string", _ => Eq(SMap.get(s, "10"), Some('a'))), }) diff --git a/tests/tests/src/option_repr_test.mjs b/tests/tests/src/option_repr_test.mjs index d67be245ef..ce732629a1 100644 --- a/tests/tests/src/option_repr_test.mjs +++ b/tests/tests/src/option_repr_test.mjs @@ -175,7 +175,7 @@ let xs = { tl: /* [] */0 }; -b("File \"option_repr_test.res\", line 125, characters 3-10", Belt_List.every(xs, x => x)); +b("File \"option_repr_test.res\", line 125, characters 2-9", Belt_List.every(xs, x => x)); let xs_0$1 = Primitive_object.lessthan(Primitive_option.some(undefined), 3) && Primitive_object.greaterthan(3, Primitive_option.some(undefined)); @@ -216,7 +216,7 @@ let xs$1 = { tl: xs_1 }; -b("File \"option_repr_test.res\", line 127, characters 3-10", Belt_List.every(xs$1, x => x)); +b("File \"option_repr_test.res\", line 127, characters 2-9", Belt_List.every(xs$1, x => x)); let xs_1$1 = { hd: neqx(undefined, null), @@ -237,7 +237,7 @@ let xs$2 = { tl: xs_1$1 }; -b("File \"option_repr_test.res\", line 143, characters 3-10", Belt_List.every(xs$2, x => x)); +b("File \"option_repr_test.res\", line 143, characters 2-9", Belt_List.every(xs$2, x => x)); function v(x) { return x; diff --git a/tests/tests/src/option_repr_test.res b/tests/tests/src/option_repr_test.res index 2d2b9884f6..0a40fdbe96 100644 --- a/tests/tests/src/option_repr_test.res +++ b/tests/tests/src/option_repr_test.res @@ -122,9 +122,9 @@ let neqx = (a, b) => a != b && b != a let all_true = xs => Belt.List.every(xs, x => x) -(b(__LOC__, ...))(all_true(list{gtx(Some(Some(Js.null)), Some(None))})) +b(__LOC__, ...)(all_true(list{gtx(Some(Some(Js.null)), Some(None))})) -(b(__LOC__, ...))( +b(__LOC__, ...)( all_true(list{ ltx(Some(None), Some(Some(3))), ltx(Some(None), Some(Some(None))), @@ -140,7 +140,7 @@ let all_true = xs => Belt.List.every(xs, x => x) }), ) -(b(__LOC__, ...))( +b(__LOC__, ...)( all_true(list{ eqx(None, None), neqx(None, Some(Js.null)), diff --git a/tests/tests/src/test_string_map.res b/tests/tests/src/test_string_map.res index 187118750d..4117e351e6 100644 --- a/tests/tests/src/test_string_map.res +++ b/tests/tests/src/test_string_map.res @@ -13,12 +13,12 @@ include ( let assertion_test = () => { let m = ref(StringMap.empty) let count = 1000000 - (timing("building", ...))(_ => + timing("building", ...)(_ => for i in 0 to count { m := m.contents->StringMap.set(Js.Int.toString(i), Js.Int.toString(i)) } ) - (timing("querying", ...))(_ => + timing("querying", ...)(_ => for i in 0 to count { m.contents->StringMap.get(Js.Int.toString(i))->ignore } diff --git a/tests/tools_tests/ppx/TestPpx.res b/tests/tools_tests/ppx/TestPpx.res index 641821fb6d..5e01438c9f 100644 --- a/tests/tools_tests/ppx/TestPpx.res +++ b/tests/tools_tests/ppx/TestPpx.res @@ -42,3 +42,6 @@ let async_foo = async (x, y) => { let b: promise = async_succ(y) (await a) + (await b) } + +let add = (x, y) => x + y +let partial_add = add(3, ...) diff --git a/tests/tools_tests/src/expected/TestPpx.res.jsout b/tests/tools_tests/src/expected/TestPpx.res.jsout index bcd68f7e14..9249f7fc53 100644 --- a/tests/tools_tests/src/expected/TestPpx.res.jsout +++ b/tests/tools_tests/src/expected/TestPpx.res.jsout @@ -51,6 +51,14 @@ async function async_foo(x, y) { return await a + await b | 0; } +function add(x, y) { + return x + y | 0; +} + +function partial_add(extra) { + return 3 + extra | 0; +} + let a = "A"; let b = "B"; @@ -67,4 +75,6 @@ exports.fpromise = fpromise; exports.Uncurried = Uncurried; exports.async_succ = async_succ; exports.async_foo = async_foo; +exports.add = add; +exports.partial_add = partial_add; /* Not a pure module */