From 26a098dc0622fd2ea842837bf2419b7401b6a41f Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Tue, 22 Nov 2022 13:08:01 +0100 Subject: [PATCH 1/6] Process uncurried application in the type checker. - Do the processing of uncurried application in the type checker. - Add support for default arguments in uncurried functions. - Add custom error messages for uncurried application. - Uncurried pipe processing does not require special handling. The current encoding is based on arity. To support default arguments one cannot just look at the number of supplied arguments, but to know whether the required arguments are supplied one needs to inspect the function type. --- .../expected/arity_mismatch.res.expected | 3 +- .../expected/arity_mismatch2.res.expected | 3 +- .../method_arity_mismatch.res.expected | 3 +- .../expected/warnings4.res.expected | 2 +- .../expected/warnings5.res.expected | 2 +- jscomp/frontend/ast_attributes.ml | 3 +- jscomp/frontend/ast_attributes.mli | 2 +- jscomp/frontend/ast_exp_apply.ml | 52 +---- jscomp/frontend/ast_uncurry_apply.ml | 14 +- jscomp/frontend/ast_uncurry_apply.mli | 1 - jscomp/ml/typecore.ml | 107 ++++++++--- jscomp/ml/typecore.mli | 1 + jscomp/test/uncurried_cast.js | 13 +- lib/4.06.1/unstable/js_compiler.ml | 180 ++++++++++-------- lib/4.06.1/unstable/js_playground_compiler.ml | 180 ++++++++++-------- lib/4.06.1/whole_compiler.ml | 180 ++++++++++-------- 16 files changed, 406 insertions(+), 340 deletions(-) diff --git a/jscomp/build_tests/super_errors/expected/arity_mismatch.res.expected b/jscomp/build_tests/super_errors/expected/arity_mismatch.res.expected index 0fd6483ce5..66063e76f9 100644 --- a/jscomp/build_tests/super_errors/expected/arity_mismatch.res.expected +++ b/jscomp/build_tests/super_errors/expected/arity_mismatch.res.expected @@ -6,4 +6,5 @@ 2 │ let makeVariables = makeVar(.~f=f => f) 3 │ - This function expected 2 arguments, but got 1 \ No newline at end of file + This uncurried function has type (. ~f: 'a => 'a, unit) => int + It is applied with 1 arguments but it requires 2. \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/arity_mismatch2.res.expected b/jscomp/build_tests/super_errors/expected/arity_mismatch2.res.expected index 716852b991..0bd3bd998c 100644 --- a/jscomp/build_tests/super_errors/expected/arity_mismatch2.res.expected +++ b/jscomp/build_tests/super_errors/expected/arity_mismatch2.res.expected @@ -6,4 +6,5 @@ 2 │ let makeVariables = makeVar(. 1, 2, 3) 3 │ - This function expected 2 arguments, but got 3 \ No newline at end of file + This uncurried function has type (. 'a, unit) => int + It is applied with 3 arguments but it requires 2. \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/method_arity_mismatch.res.expected b/jscomp/build_tests/super_errors/expected/method_arity_mismatch.res.expected index 52bf52d00c..e57bb53de8 100644 --- a/jscomp/build_tests/super_errors/expected/method_arity_mismatch.res.expected +++ b/jscomp/build_tests/super_errors/expected/method_arity_mismatch.res.expected @@ -8,4 +8,5 @@ 4 │ } 5 │ - This function expected 2 arguments, but got 1 \ No newline at end of file + This uncurried function has type (. int, int) => unit + It is applied with 1 arguments but it requires 2. \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/warnings4.res.expected b/jscomp/build_tests/super_errors/expected/warnings4.res.expected index 22bb562fd1..dfa23450b8 100644 --- a/jscomp/build_tests/super_errors/expected/warnings4.res.expected +++ b/jscomp/build_tests/super_errors/expected/warnings4.res.expected @@ -10,4 +10,4 @@ 14 │ You forgot to handle a possible case here, for example: - #second(_) | #fourth | #third + #second(_) | #fourth | #third \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/warnings5.res.expected b/jscomp/build_tests/super_errors/expected/warnings5.res.expected index 0fc28d16ec..91026741ff 100644 --- a/jscomp/build_tests/super_errors/expected/warnings5.res.expected +++ b/jscomp/build_tests/super_errors/expected/warnings5.res.expected @@ -187,4 +187,4 @@ Either bind these labels explicitly or add ', _' to the pattern. 60 │ You forgot to handle a possible case here, for example: - (_, true) + (_, true) \ No newline at end of file diff --git a/jscomp/frontend/ast_attributes.ml b/jscomp/frontend/ast_attributes.ml index 957ba112d2..c8c90d01ae 100644 --- a/jscomp/frontend/ast_attributes.ml +++ b/jscomp/frontend/ast_attributes.ml @@ -341,8 +341,7 @@ let locg = Location.none let is_bs (attr : attr) = match attr with { Location.txt = "bs"; _ }, _ -> true | _ -> false -let is_res_uapp (attr : attr) = - match attr with { Location.txt = "res.uapp"; _ }, _ -> true | _ -> false +let res_uapp : attr = ({ txt = "res.uapp"; loc = locg }, Ast_payload.empty) let bs_get : attr = ({ txt = "bs.get"; loc = locg }, Ast_payload.empty) diff --git a/jscomp/frontend/ast_attributes.mli b/jscomp/frontend/ast_attributes.mli index 15b780a8fe..6a13c06c64 100644 --- a/jscomp/frontend/ast_attributes.mli +++ b/jscomp/frontend/ast_attributes.mli @@ -73,7 +73,7 @@ val is_bs : attr -> bool val is_bs_as : attr -> bool *) (* Attribute for uncurried application coming from the ReScript parser *) -val is_res_uapp : attr -> bool +val res_uapp : attr val bs_get : attr diff --git a/jscomp/frontend/ast_exp_apply.ml b/jscomp/frontend/ast_exp_apply.ml index 1ec8148298..a0d078e553 100644 --- a/jscomp/frontend/ast_exp_apply.ml +++ b/jscomp/frontend/ast_exp_apply.ml @@ -124,7 +124,7 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { pexp_desc = Pexp_apply (fn1, (Nolabel, a) :: args); pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; + pexp_attributes = e.pexp_attributes @ f.pexp_attributes; } | Pexp_tuple xs -> bound a (fun bounded_obj_arg -> @@ -158,38 +158,16 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) }) | _ -> ( match - ( Ext_list.exclude_with_val f_.pexp_attributes (fun a -> - Ast_attributes.is_bs a - || Ast_attributes.is_res_uapp a), + ( Ext_list.exclude_with_val f_.pexp_attributes + Ast_attributes.is_bs, f_.pexp_desc ) with - | Some other_attributes, Pexp_apply (fn1, args) -> - (* a |. f b c [@bs] - Cannot process uncurried application early as the arity is wip *) - let fn1 = self.expr self fn1 in - let args = - args |> List.map (fun (l, e) -> (l, self.expr self e)) - in - Bs_ast_invariant.warn_discarded_unused_attributes - fn1.pexp_attributes; - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:(op = "|.") - e.pexp_loc self fn1 ((Nolabel, a) :: args); - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes @ other_attributes; - } | _ when op = "|.u" -> (* a |.u f Uncurried unary application *) - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self f - [ (Nolabel, a) ]; - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; - } + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property @@ -289,21 +267,7 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { e with pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:true e.pexp_loc - self fn args; + Ast_uncurry_apply.uncurry_fn_apply e.pexp_loc self fn args; pexp_attributes; } - | None -> ( - match - Ext_list.exclude_with_val e.pexp_attributes - Ast_attributes.is_res_uapp - with - | Some pexp_attributes -> - { - e with - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self fn args; - pexp_attributes; - } - | None -> default_expr_mapper self e))) + | None -> default_expr_mapper self e)) diff --git a/jscomp/frontend/ast_uncurry_apply.ml b/jscomp/frontend/ast_uncurry_apply.ml index 8d8d70eed0..1032974506 100644 --- a/jscomp/frontend/ast_uncurry_apply.ml +++ b/jscomp/frontend/ast_uncurry_apply.ml @@ -44,9 +44,8 @@ let opaque_full_apply ~loc (e : exp) : Parsetree.expression_desc = [ (Nolabel, e) ], Typ.any ~loc () ) -let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) - (obj : Parsetree.expression) (args : Ast_compatible.args) - (cb : loc -> exp -> exp) = +let generic_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) + (args : Ast_compatible.args) (cb : loc -> exp -> exp) = let obj = self.expr self obj in let args = Ext_list.map args (fun (lbl, e) -> @@ -58,8 +57,7 @@ let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) match args with | [ (Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) }); - ] - when arity0 -> + ] -> [] | _ -> args in @@ -130,9 +128,9 @@ let method_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) ]) args) -let uncurry_fn_apply ~arity0 loc self fn args = - generic_apply ~arity0 loc self fn args (fun _ obj -> obj) +let uncurry_fn_apply loc self fn args = + generic_apply loc self fn args (fun _ obj -> obj) let property_apply loc self obj name args = - generic_apply ~arity0:true loc self obj args (fun loc obj -> + generic_apply loc self obj args (fun loc obj -> Exp.send ~loc obj { txt = name; loc }) diff --git a/jscomp/frontend/ast_uncurry_apply.mli b/jscomp/frontend/ast_uncurry_apply.mli index a402c08004..81827af52b 100644 --- a/jscomp/frontend/ast_uncurry_apply.mli +++ b/jscomp/frontend/ast_uncurry_apply.mli @@ -25,7 +25,6 @@ (* TODO: the interface is not reusable, it depends on too much context *) val uncurry_fn_apply : - arity0:bool -> Location.t -> Bs_ast_mapper.mapper -> Parsetree.expression -> diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index d42e67c39e..d36bb7ef25 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -73,6 +73,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -2015,15 +2016,35 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); wrap_trace_gadt_instances env (lower_args env []) ty; begin_def (); - let (args, ty_res) = type_application env funct sargs in + let uncurried = Ext_list.exists sexp.pexp_attributes (fun ({txt },_) -> txt = "res.uapp") in + let (args, ty_res, fully_applied) = type_application uncurried env funct sargs in end_def (); unify_var env (newvar()) funct.exp_type; - rue { - exp_desc = Texp_apply(funct, args); - exp_loc = loc; exp_extra = []; - exp_type = ty_res; - exp_attributes = sexp.pexp_attributes; - exp_env = env } + + let mk_exp exp_desc exp_type = + { exp_desc; + exp_loc = Location.none; exp_extra = []; + exp_type; + exp_attributes = []; + exp_env = env } in + let apply_internal name e = + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in + let (path, desc) = Env.lookup_value lid env in + let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in + mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + + let mk_apply funct args = + rue { + exp_desc = Texp_apply(funct, args); + exp_loc = loc; exp_extra = []; + exp_type = ty_res; + exp_attributes = sexp.pexp_attributes; + exp_env = env } in + + if fully_applied then + rue (apply_internal "opaqueFullApply" (mk_apply (apply_internal "opaque" funct) args)) + else + rue (mk_apply funct args) | Pexp_match(sarg, caselist) -> begin_def (); let arg = type_exp env sarg in @@ -2939,7 +2960,7 @@ and type_argument ?recarg env sarg ty_expected' ty_expected = unify_exp env texp ty_expected; texp -and type_application env funct (sargs : sargs) : targs * Types.type_expr = +and type_application uncurried env funct (sargs : sargs) : targs * Types.type_expr * bool = (* funct.exp_type may be generic *) let result_type omitted ty_fun = List.fold_left @@ -2951,25 +2972,49 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = tvar || List.mem l ls in let ignored = ref [] in - let extract_uncurried_type t = + let mk_js_fn arity t = + let a = "arity" ^ string_of_int arity in + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in + let path = Env.lookup_type lid env in + newconstr path [t] in + let has_uncurried_type t = match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),_,_),[t],_) -> t - | _ -> t in - let lower_uncurried_arity ~nargs t newT = - match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[_],_) -> + | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[t],_) -> let arity = if String.sub a 0 5 = "arity" then int_of_string (String.sub a 5 (String.length a - 5)) else 0 in + Some (arity, t) + | _ -> None in + let force_uncurried_type funct = + match has_uncurried_type funct.exp_type with + | None -> + let arity = List.length sargs in + let js_fn = mk_js_fn arity (newvar()) in + unify_exp env funct js_fn + | Some _ -> () in + let extract_uncurried_type t = + match has_uncurried_type t with + | Some (arity, t1) -> + if List.length sargs > arity then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + t1 + | None -> t in + let update_uncurried_arity ~nargs t newT = + match has_uncurried_type t with + | Some (arity, _) -> let newarity = arity - nargs in - if newarity > 0 then - let a = "arity" ^ string_of_int newarity in - let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in - let path = Env.lookup_type lid env in - newconstr path [newT] - else newT - | _ -> newT + if newarity < 0 then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, true))); + let fully_applied = newarity = 0 in + if uncurried && not fully_applied then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + let newT = if fully_applied then newT else mk_js_fn newarity newT in + (fully_applied, newT) + | _ -> (false, newT) in let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = @@ -3078,14 +3123,14 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = Delayed_checks.add_delayed_check (fun () -> check_application_result env false exp) | _ -> () end; - ([Nolabel, Some exp], ty_res) + ([Nolabel, Some exp], ty_res, false) | _ -> + if uncurried then force_uncurried_type funct; let ty = extract_uncurried_type funct.exp_type in let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in - let ret_t = - if funct.exp_type == ty then ret_t - else lower_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in - targs, ret_t + let fully_applied, ret_t = + update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in + targs, ret_t, fully_applied and type_construct env loc lid sarg ty_expected attrs = let opath = @@ -3821,6 +3866,16 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." + | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" + args (if args = 0 then "" else "s") arity + | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" + let super_report_error_no_wrap_printing_env = report_error diff --git a/jscomp/ml/typecore.mli b/jscomp/ml/typecore.mli index 8f788b65c5..49918ecf6f 100644 --- a/jscomp/ml/typecore.mli +++ b/jscomp/ml/typecore.mli @@ -109,6 +109,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error diff --git a/jscomp/test/uncurried_cast.js b/jscomp/test/uncurried_cast.js index 7356f89cff..db82191d3e 100644 --- a/jscomp/test/uncurried_cast.js +++ b/jscomp/test/uncurried_cast.js @@ -22,10 +22,9 @@ var Uncurried = { var E = /* @__PURE__ */Caml_exceptions.create("Uncurried_cast.E"); function testRaise(param) { - throw { - RE_EXN_ID: E, - Error: new Error() - }; + return raise({ + RE_EXN_ID: E + }); } var l = map({ @@ -50,9 +49,9 @@ function partial(param) { return map(partial_arg, param); } -var ll = Curry._1(partial, (function (x) { - return x + 1 | 0; - })); +var ll = partial(function (x) { + return x + 1 | 0; + }); function withOpts(xOpt, y, zOpt, w) { var x = xOpt !== undefined ? xOpt : 3; diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 502ef0626b..2ee1fdeef5 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -40695,6 +40695,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -40802,6 +40803,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -42744,15 +42746,35 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); wrap_trace_gadt_instances env (lower_args env []) ty; begin_def (); - let (args, ty_res) = type_application env funct sargs in + let uncurried = Ext_list.exists sexp.pexp_attributes (fun ({txt },_) -> txt = "res.uapp") in + let (args, ty_res, fully_applied) = type_application uncurried env funct sargs in end_def (); unify_var env (newvar()) funct.exp_type; - rue { - exp_desc = Texp_apply(funct, args); - exp_loc = loc; exp_extra = []; - exp_type = ty_res; - exp_attributes = sexp.pexp_attributes; - exp_env = env } + + let mk_exp exp_desc exp_type = + { exp_desc; + exp_loc = Location.none; exp_extra = []; + exp_type; + exp_attributes = []; + exp_env = env } in + let apply_internal name e = + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in + let (path, desc) = Env.lookup_value lid env in + let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in + mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + + let mk_apply funct args = + rue { + exp_desc = Texp_apply(funct, args); + exp_loc = loc; exp_extra = []; + exp_type = ty_res; + exp_attributes = sexp.pexp_attributes; + exp_env = env } in + + if fully_applied then + rue (apply_internal "opaqueFullApply" (mk_apply (apply_internal "opaque" funct) args)) + else + rue (mk_apply funct args) | Pexp_match(sarg, caselist) -> begin_def (); let arg = type_exp env sarg in @@ -43668,7 +43690,7 @@ and type_argument ?recarg env sarg ty_expected' ty_expected = unify_exp env texp ty_expected; texp -and type_application env funct (sargs : sargs) : targs * Types.type_expr = +and type_application uncurried env funct (sargs : sargs) : targs * Types.type_expr * bool = (* funct.exp_type may be generic *) let result_type omitted ty_fun = List.fold_left @@ -43680,25 +43702,49 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = tvar || List.mem l ls in let ignored = ref [] in - let extract_uncurried_type t = + let mk_js_fn arity t = + let a = "arity" ^ string_of_int arity in + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in + let path = Env.lookup_type lid env in + newconstr path [t] in + let has_uncurried_type t = match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),_,_),[t],_) -> t - | _ -> t in - let lower_uncurried_arity ~nargs t newT = - match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[_],_) -> + | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[t],_) -> let arity = if String.sub a 0 5 = "arity" then int_of_string (String.sub a 5 (String.length a - 5)) else 0 in + Some (arity, t) + | _ -> None in + let force_uncurried_type funct = + match has_uncurried_type funct.exp_type with + | None -> + let arity = List.length sargs in + let js_fn = mk_js_fn arity (newvar()) in + unify_exp env funct js_fn + | Some _ -> () in + let extract_uncurried_type t = + match has_uncurried_type t with + | Some (arity, t1) -> + if List.length sargs > arity then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + t1 + | None -> t in + let update_uncurried_arity ~nargs t newT = + match has_uncurried_type t with + | Some (arity, _) -> let newarity = arity - nargs in - if newarity > 0 then - let a = "arity" ^ string_of_int newarity in - let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in - let path = Env.lookup_type lid env in - newconstr path [newT] - else newT - | _ -> newT + if newarity < 0 then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, true))); + let fully_applied = newarity = 0 in + if uncurried && not fully_applied then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + let newT = if fully_applied then newT else mk_js_fn newarity newT in + (fully_applied, newT) + | _ -> (false, newT) in let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = @@ -43807,14 +43853,14 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = Delayed_checks.add_delayed_check (fun () -> check_application_result env false exp) | _ -> () end; - ([Nolabel, Some exp], ty_res) + ([Nolabel, Some exp], ty_res, false) | _ -> + if uncurried then force_uncurried_type funct; let ty = extract_uncurried_type funct.exp_type in let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in - let ret_t = - if funct.exp_type == ty then ret_t - else lower_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in - targs, ret_t + let fully_applied, ret_t = + update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in + targs, ret_t, fully_applied and type_construct env loc lid sarg ty_expected attrs = let opath = @@ -44550,6 +44596,16 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." + | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" + args (if args = 0 then "" else "s") arity + | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" + let super_report_error_no_wrap_printing_env = report_error @@ -145139,7 +145195,7 @@ val is_bs : attr -> bool val is_bs_as : attr -> bool *) (* Attribute for uncurried application coming from the ReScript parser *) -val is_res_uapp : attr -> bool +val res_uapp : attr val bs_get : attr @@ -145503,8 +145559,7 @@ let locg = Location.none let is_bs (attr : attr) = match attr with { Location.txt = "bs"; _ }, _ -> true | _ -> false -let is_res_uapp (attr : attr) = - match attr with { Location.txt = "res.uapp"; _ }, _ -> true | _ -> false +let res_uapp : attr = ({ txt = "res.uapp"; loc = locg }, Ast_payload.empty) let bs_get : attr = ({ txt = "bs.get"; loc = locg }, Ast_payload.empty) @@ -148484,7 +148539,6 @@ module Ast_uncurry_apply : sig (* TODO: the interface is not reusable, it depends on too much context *) val uncurry_fn_apply : - arity0:bool -> Location.t -> Bs_ast_mapper.mapper -> Parsetree.expression -> @@ -148558,9 +148612,8 @@ let opaque_full_apply ~loc (e : exp) : Parsetree.expression_desc = [ (Nolabel, e) ], Typ.any ~loc () ) -let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) - (obj : Parsetree.expression) (args : Ast_compatible.args) - (cb : loc -> exp -> exp) = +let generic_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) + (args : Ast_compatible.args) (cb : loc -> exp -> exp) = let obj = self.expr self obj in let args = Ext_list.map args (fun (lbl, e) -> @@ -148572,8 +148625,7 @@ let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) match args with | [ (Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) }); - ] - when arity0 -> + ] -> [] | _ -> args in @@ -148644,11 +148696,11 @@ let method_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) ]) args) -let uncurry_fn_apply ~arity0 loc self fn args = - generic_apply ~arity0 loc self fn args (fun _ obj -> obj) +let uncurry_fn_apply loc self fn args = + generic_apply loc self fn args (fun _ obj -> obj) let property_apply loc self obj name args = - generic_apply ~arity0:true loc self obj args (fun loc obj -> + generic_apply loc self obj args (fun loc obj -> Exp.send ~loc obj { txt = name; loc }) end @@ -150501,7 +150553,7 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { pexp_desc = Pexp_apply (fn1, (Nolabel, a) :: args); pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; + pexp_attributes = e.pexp_attributes @ f.pexp_attributes; } | Pexp_tuple xs -> bound a (fun bounded_obj_arg -> @@ -150535,38 +150587,16 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) }) | _ -> ( match - ( Ext_list.exclude_with_val f_.pexp_attributes (fun a -> - Ast_attributes.is_bs a - || Ast_attributes.is_res_uapp a), + ( Ext_list.exclude_with_val f_.pexp_attributes + Ast_attributes.is_bs, f_.pexp_desc ) with - | Some other_attributes, Pexp_apply (fn1, args) -> - (* a |. f b c [@bs] - Cannot process uncurried application early as the arity is wip *) - let fn1 = self.expr self fn1 in - let args = - args |> List.map (fun (l, e) -> (l, self.expr self e)) - in - Bs_ast_invariant.warn_discarded_unused_attributes - fn1.pexp_attributes; - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:(op = "|.") - e.pexp_loc self fn1 ((Nolabel, a) :: args); - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes @ other_attributes; - } | _ when op = "|.u" -> (* a |.u f Uncurried unary application *) - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self f - [ (Nolabel, a) ]; - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; - } + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property @@ -150666,24 +150696,10 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { e with pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:true e.pexp_loc - self fn args; + Ast_uncurry_apply.uncurry_fn_apply e.pexp_loc self fn args; pexp_attributes; } - | None -> ( - match - Ext_list.exclude_with_val e.pexp_attributes - Ast_attributes.is_res_uapp - with - | Some pexp_attributes -> - { - e with - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self fn args; - pexp_attributes; - } - | None -> default_expr_mapper self e))) + | None -> default_expr_mapper self e)) end module Ast_exp : sig diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index 6de13753f8..8469cfbb3b 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -40695,6 +40695,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -40802,6 +40803,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -42744,15 +42746,35 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); wrap_trace_gadt_instances env (lower_args env []) ty; begin_def (); - let (args, ty_res) = type_application env funct sargs in + let uncurried = Ext_list.exists sexp.pexp_attributes (fun ({txt },_) -> txt = "res.uapp") in + let (args, ty_res, fully_applied) = type_application uncurried env funct sargs in end_def (); unify_var env (newvar()) funct.exp_type; - rue { - exp_desc = Texp_apply(funct, args); - exp_loc = loc; exp_extra = []; - exp_type = ty_res; - exp_attributes = sexp.pexp_attributes; - exp_env = env } + + let mk_exp exp_desc exp_type = + { exp_desc; + exp_loc = Location.none; exp_extra = []; + exp_type; + exp_attributes = []; + exp_env = env } in + let apply_internal name e = + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in + let (path, desc) = Env.lookup_value lid env in + let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in + mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + + let mk_apply funct args = + rue { + exp_desc = Texp_apply(funct, args); + exp_loc = loc; exp_extra = []; + exp_type = ty_res; + exp_attributes = sexp.pexp_attributes; + exp_env = env } in + + if fully_applied then + rue (apply_internal "opaqueFullApply" (mk_apply (apply_internal "opaque" funct) args)) + else + rue (mk_apply funct args) | Pexp_match(sarg, caselist) -> begin_def (); let arg = type_exp env sarg in @@ -43668,7 +43690,7 @@ and type_argument ?recarg env sarg ty_expected' ty_expected = unify_exp env texp ty_expected; texp -and type_application env funct (sargs : sargs) : targs * Types.type_expr = +and type_application uncurried env funct (sargs : sargs) : targs * Types.type_expr * bool = (* funct.exp_type may be generic *) let result_type omitted ty_fun = List.fold_left @@ -43680,25 +43702,49 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = tvar || List.mem l ls in let ignored = ref [] in - let extract_uncurried_type t = + let mk_js_fn arity t = + let a = "arity" ^ string_of_int arity in + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in + let path = Env.lookup_type lid env in + newconstr path [t] in + let has_uncurried_type t = match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),_,_),[t],_) -> t - | _ -> t in - let lower_uncurried_arity ~nargs t newT = - match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[_],_) -> + | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[t],_) -> let arity = if String.sub a 0 5 = "arity" then int_of_string (String.sub a 5 (String.length a - 5)) else 0 in + Some (arity, t) + | _ -> None in + let force_uncurried_type funct = + match has_uncurried_type funct.exp_type with + | None -> + let arity = List.length sargs in + let js_fn = mk_js_fn arity (newvar()) in + unify_exp env funct js_fn + | Some _ -> () in + let extract_uncurried_type t = + match has_uncurried_type t with + | Some (arity, t1) -> + if List.length sargs > arity then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + t1 + | None -> t in + let update_uncurried_arity ~nargs t newT = + match has_uncurried_type t with + | Some (arity, _) -> let newarity = arity - nargs in - if newarity > 0 then - let a = "arity" ^ string_of_int newarity in - let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in - let path = Env.lookup_type lid env in - newconstr path [newT] - else newT - | _ -> newT + if newarity < 0 then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, true))); + let fully_applied = newarity = 0 in + if uncurried && not fully_applied then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + let newT = if fully_applied then newT else mk_js_fn newarity newT in + (fully_applied, newT) + | _ -> (false, newT) in let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = @@ -43807,14 +43853,14 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = Delayed_checks.add_delayed_check (fun () -> check_application_result env false exp) | _ -> () end; - ([Nolabel, Some exp], ty_res) + ([Nolabel, Some exp], ty_res, false) | _ -> + if uncurried then force_uncurried_type funct; let ty = extract_uncurried_type funct.exp_type in let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in - let ret_t = - if funct.exp_type == ty then ret_t - else lower_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in - targs, ret_t + let fully_applied, ret_t = + update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in + targs, ret_t, fully_applied and type_construct env loc lid sarg ty_expected attrs = let opath = @@ -44550,6 +44596,16 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." + | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" + args (if args = 0 then "" else "s") arity + | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" + let super_report_error_no_wrap_printing_env = report_error @@ -145139,7 +145195,7 @@ val is_bs : attr -> bool val is_bs_as : attr -> bool *) (* Attribute for uncurried application coming from the ReScript parser *) -val is_res_uapp : attr -> bool +val res_uapp : attr val bs_get : attr @@ -145503,8 +145559,7 @@ let locg = Location.none let is_bs (attr : attr) = match attr with { Location.txt = "bs"; _ }, _ -> true | _ -> false -let is_res_uapp (attr : attr) = - match attr with { Location.txt = "res.uapp"; _ }, _ -> true | _ -> false +let res_uapp : attr = ({ txt = "res.uapp"; loc = locg }, Ast_payload.empty) let bs_get : attr = ({ txt = "bs.get"; loc = locg }, Ast_payload.empty) @@ -148484,7 +148539,6 @@ module Ast_uncurry_apply : sig (* TODO: the interface is not reusable, it depends on too much context *) val uncurry_fn_apply : - arity0:bool -> Location.t -> Bs_ast_mapper.mapper -> Parsetree.expression -> @@ -148558,9 +148612,8 @@ let opaque_full_apply ~loc (e : exp) : Parsetree.expression_desc = [ (Nolabel, e) ], Typ.any ~loc () ) -let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) - (obj : Parsetree.expression) (args : Ast_compatible.args) - (cb : loc -> exp -> exp) = +let generic_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) + (args : Ast_compatible.args) (cb : loc -> exp -> exp) = let obj = self.expr self obj in let args = Ext_list.map args (fun (lbl, e) -> @@ -148572,8 +148625,7 @@ let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) match args with | [ (Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) }); - ] - when arity0 -> + ] -> [] | _ -> args in @@ -148644,11 +148696,11 @@ let method_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) ]) args) -let uncurry_fn_apply ~arity0 loc self fn args = - generic_apply ~arity0 loc self fn args (fun _ obj -> obj) +let uncurry_fn_apply loc self fn args = + generic_apply loc self fn args (fun _ obj -> obj) let property_apply loc self obj name args = - generic_apply ~arity0:true loc self obj args (fun loc obj -> + generic_apply loc self obj args (fun loc obj -> Exp.send ~loc obj { txt = name; loc }) end @@ -150501,7 +150553,7 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { pexp_desc = Pexp_apply (fn1, (Nolabel, a) :: args); pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; + pexp_attributes = e.pexp_attributes @ f.pexp_attributes; } | Pexp_tuple xs -> bound a (fun bounded_obj_arg -> @@ -150535,38 +150587,16 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) }) | _ -> ( match - ( Ext_list.exclude_with_val f_.pexp_attributes (fun a -> - Ast_attributes.is_bs a - || Ast_attributes.is_res_uapp a), + ( Ext_list.exclude_with_val f_.pexp_attributes + Ast_attributes.is_bs, f_.pexp_desc ) with - | Some other_attributes, Pexp_apply (fn1, args) -> - (* a |. f b c [@bs] - Cannot process uncurried application early as the arity is wip *) - let fn1 = self.expr self fn1 in - let args = - args |> List.map (fun (l, e) -> (l, self.expr self e)) - in - Bs_ast_invariant.warn_discarded_unused_attributes - fn1.pexp_attributes; - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:(op = "|.") - e.pexp_loc self fn1 ((Nolabel, a) :: args); - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes @ other_attributes; - } | _ when op = "|.u" -> (* a |.u f Uncurried unary application *) - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self f - [ (Nolabel, a) ]; - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; - } + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property @@ -150666,24 +150696,10 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { e with pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:true e.pexp_loc - self fn args; + Ast_uncurry_apply.uncurry_fn_apply e.pexp_loc self fn args; pexp_attributes; } - | None -> ( - match - Ext_list.exclude_with_val e.pexp_attributes - Ast_attributes.is_res_uapp - with - | Some pexp_attributes -> - { - e with - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self fn args; - pexp_attributes; - } - | None -> default_expr_mapper self e))) + | None -> default_expr_mapper self e)) end module Ast_exp : sig diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index 1fede48599..e6e418274c 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -95693,6 +95693,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -95800,6 +95801,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal + | Uncurried_arity_mismatch of type_expr * int * int * bool exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -97742,15 +97744,35 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); wrap_trace_gadt_instances env (lower_args env []) ty; begin_def (); - let (args, ty_res) = type_application env funct sargs in + let uncurried = Ext_list.exists sexp.pexp_attributes (fun ({txt },_) -> txt = "res.uapp") in + let (args, ty_res, fully_applied) = type_application uncurried env funct sargs in end_def (); unify_var env (newvar()) funct.exp_type; - rue { - exp_desc = Texp_apply(funct, args); - exp_loc = loc; exp_extra = []; - exp_type = ty_res; - exp_attributes = sexp.pexp_attributes; - exp_env = env } + + let mk_exp exp_desc exp_type = + { exp_desc; + exp_loc = Location.none; exp_extra = []; + exp_type; + exp_attributes = []; + exp_env = env } in + let apply_internal name e = + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in + let (path, desc) = Env.lookup_value lid env in + let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in + mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + + let mk_apply funct args = + rue { + exp_desc = Texp_apply(funct, args); + exp_loc = loc; exp_extra = []; + exp_type = ty_res; + exp_attributes = sexp.pexp_attributes; + exp_env = env } in + + if fully_applied then + rue (apply_internal "opaqueFullApply" (mk_apply (apply_internal "opaque" funct) args)) + else + rue (mk_apply funct args) | Pexp_match(sarg, caselist) -> begin_def (); let arg = type_exp env sarg in @@ -98666,7 +98688,7 @@ and type_argument ?recarg env sarg ty_expected' ty_expected = unify_exp env texp ty_expected; texp -and type_application env funct (sargs : sargs) : targs * Types.type_expr = +and type_application uncurried env funct (sargs : sargs) : targs * Types.type_expr * bool = (* funct.exp_type may be generic *) let result_type omitted ty_fun = List.fold_left @@ -98678,25 +98700,49 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = tvar || List.mem l ls in let ignored = ref [] in - let extract_uncurried_type t = + let mk_js_fn arity t = + let a = "arity" ^ string_of_int arity in + let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in + let path = Env.lookup_type lid env in + newconstr path [t] in + let has_uncurried_type t = match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),_,_),[t],_) -> t - | _ -> t in - let lower_uncurried_arity ~nargs t newT = - match (expand_head env t).desc with - | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[_],_) -> + | Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),[t],_) -> let arity = if String.sub a 0 5 = "arity" then int_of_string (String.sub a 5 (String.length a - 5)) else 0 in + Some (arity, t) + | _ -> None in + let force_uncurried_type funct = + match has_uncurried_type funct.exp_type with + | None -> + let arity = List.length sargs in + let js_fn = mk_js_fn arity (newvar()) in + unify_exp env funct js_fn + | Some _ -> () in + let extract_uncurried_type t = + match has_uncurried_type t with + | Some (arity, t1) -> + if List.length sargs > arity then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + t1 + | None -> t in + let update_uncurried_arity ~nargs t newT = + match has_uncurried_type t with + | Some (arity, _) -> let newarity = arity - nargs in - if newarity > 0 then - let a = "arity" ^ string_of_int newarity in - let lid:Longident.t = Ldot (Ldot (Lident "Js", "Fn"), a) in - let path = Env.lookup_type lid env in - newconstr path [newT] - else newT - | _ -> newT + if newarity < 0 then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, true))); + let fully_applied = newarity = 0 in + if uncurried && not fully_applied then + raise(Error(funct.exp_loc, env, + Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + let newT = if fully_applied then newT else mk_js_fn newarity newT in + (fully_applied, newT) + | _ -> (false, newT) in let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = @@ -98805,14 +98851,14 @@ and type_application env funct (sargs : sargs) : targs * Types.type_expr = Delayed_checks.add_delayed_check (fun () -> check_application_result env false exp) | _ -> () end; - ([Nolabel, Some exp], ty_res) + ([Nolabel, Some exp], ty_res, false) | _ -> + if uncurried then force_uncurried_type funct; let ty = extract_uncurried_type funct.exp_type in let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in - let ret_t = - if funct.exp_type == ty then ret_t - else lower_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in - targs, ret_t + let fully_applied, ret_t = + update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in + targs, ret_t, fully_applied and type_construct env loc lid sarg ty_expected attrs = let opath = @@ -99548,6 +99594,16 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." + | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" + args (if args = 0 then "" else "s") arity + | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> + fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" + type_expr typ; + fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" + let super_report_error_no_wrap_printing_env = report_error @@ -155423,7 +155479,7 @@ val is_bs : attr -> bool val is_bs_as : attr -> bool *) (* Attribute for uncurried application coming from the ReScript parser *) -val is_res_uapp : attr -> bool +val res_uapp : attr val bs_get : attr @@ -155787,8 +155843,7 @@ let locg = Location.none let is_bs (attr : attr) = match attr with { Location.txt = "bs"; _ }, _ -> true | _ -> false -let is_res_uapp (attr : attr) = - match attr with { Location.txt = "res.uapp"; _ }, _ -> true | _ -> false +let res_uapp : attr = ({ txt = "res.uapp"; loc = locg }, Ast_payload.empty) let bs_get : attr = ({ txt = "bs.get"; loc = locg }, Ast_payload.empty) @@ -158768,7 +158823,6 @@ module Ast_uncurry_apply : sig (* TODO: the interface is not reusable, it depends on too much context *) val uncurry_fn_apply : - arity0:bool -> Location.t -> Bs_ast_mapper.mapper -> Parsetree.expression -> @@ -158842,9 +158896,8 @@ let opaque_full_apply ~loc (e : exp) : Parsetree.expression_desc = [ (Nolabel, e) ], Typ.any ~loc () ) -let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) - (obj : Parsetree.expression) (args : Ast_compatible.args) - (cb : loc -> exp -> exp) = +let generic_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) + (args : Ast_compatible.args) (cb : loc -> exp -> exp) = let obj = self.expr self obj in let args = Ext_list.map args (fun (lbl, e) -> @@ -158856,8 +158909,7 @@ let generic_apply ~arity0 loc (self : Bs_ast_mapper.mapper) match args with | [ (Nolabel, { pexp_desc = Pexp_construct ({ txt = Lident "()" }, None) }); - ] - when arity0 -> + ] -> [] | _ -> args in @@ -158928,11 +158980,11 @@ let method_apply loc (self : Bs_ast_mapper.mapper) (obj : Parsetree.expression) ]) args) -let uncurry_fn_apply ~arity0 loc self fn args = - generic_apply ~arity0 loc self fn args (fun _ obj -> obj) +let uncurry_fn_apply loc self fn args = + generic_apply loc self fn args (fun _ obj -> obj) let property_apply loc self obj name args = - generic_apply ~arity0:true loc self obj args (fun loc obj -> + generic_apply loc self obj args (fun loc obj -> Exp.send ~loc obj { txt = name; loc }) end @@ -160785,7 +160837,7 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { pexp_desc = Pexp_apply (fn1, (Nolabel, a) :: args); pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; + pexp_attributes = e.pexp_attributes @ f.pexp_attributes; } | Pexp_tuple xs -> bound a (fun bounded_obj_arg -> @@ -160819,38 +160871,16 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) }) | _ -> ( match - ( Ext_list.exclude_with_val f_.pexp_attributes (fun a -> - Ast_attributes.is_bs a - || Ast_attributes.is_res_uapp a), + ( Ext_list.exclude_with_val f_.pexp_attributes + Ast_attributes.is_bs, f_.pexp_desc ) with - | Some other_attributes, Pexp_apply (fn1, args) -> - (* a |. f b c [@bs] - Cannot process uncurried application early as the arity is wip *) - let fn1 = self.expr self fn1 in - let args = - args |> List.map (fun (l, e) -> (l, self.expr self e)) - in - Bs_ast_invariant.warn_discarded_unused_attributes - fn1.pexp_attributes; - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:(op = "|.") - e.pexp_loc self fn1 ((Nolabel, a) :: args); - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes @ other_attributes; - } | _ when op = "|.u" -> (* a |.u f Uncurried unary application *) - { - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self f - [ (Nolabel, a) ]; - pexp_loc = e.pexp_loc; - pexp_attributes = e.pexp_attributes; - } + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property @@ -160950,24 +160980,10 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) { e with pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:true e.pexp_loc - self fn args; + Ast_uncurry_apply.uncurry_fn_apply e.pexp_loc self fn args; pexp_attributes; } - | None -> ( - match - Ext_list.exclude_with_val e.pexp_attributes - Ast_attributes.is_res_uapp - with - | Some pexp_attributes -> - { - e with - pexp_desc = - Ast_uncurry_apply.uncurry_fn_apply ~arity0:false - e.pexp_loc self fn args; - pexp_attributes; - } - | None -> default_expr_mapper self e))) + | None -> default_expr_mapper self e)) end module Ast_exp : sig From 173989aad37e85e9571a211e3b52af3509310a3d Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Tue, 22 Nov 2022 18:52:37 +0100 Subject: [PATCH 2/6] Give error when uncurried application tries to use label from result type. --- .../uncurried_wrong_label.res.expected | 11 ++++++ .../fixtures/uncurried_wrong_label.res | 3 ++ jscomp/ml/typecore.ml | 35 +++++++++++-------- lib/4.06.1/unstable/js_compiler.ml | 35 +++++++++++-------- lib/4.06.1/unstable/js_playground_compiler.ml | 35 +++++++++++-------- lib/4.06.1/whole_compiler.ml | 35 +++++++++++-------- 6 files changed, 94 insertions(+), 60 deletions(-) create mode 100644 jscomp/build_tests/super_errors/expected/uncurried_wrong_label.res.expected create mode 100644 jscomp/build_tests/super_errors/fixtures/uncurried_wrong_label.res diff --git a/jscomp/build_tests/super_errors/expected/uncurried_wrong_label.res.expected b/jscomp/build_tests/super_errors/expected/uncurried_wrong_label.res.expected new file mode 100644 index 0000000000..955e973b37 --- /dev/null +++ b/jscomp/build_tests/super_errors/expected/uncurried_wrong_label.res.expected @@ -0,0 +1,11 @@ + + We've found a bug for you! + /.../fixtures/uncurried_wrong_label.res:3:18 + + 1 │ let foo = (. ~x) => { let _ = (); (~y) => x+y } + 2 │ // This looks too far into the return type + 3 │ let d = foo(. ~y=3) + 4 │ + + The function applied to this argument has type (. ~x: int, ~y: int) => int +This argument cannot be applied with label ~y \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/fixtures/uncurried_wrong_label.res b/jscomp/build_tests/super_errors/fixtures/uncurried_wrong_label.res new file mode 100644 index 0000000000..aaa374699c --- /dev/null +++ b/jscomp/build_tests/super_errors/fixtures/uncurried_wrong_label.res @@ -0,0 +1,3 @@ +let foo = (. ~x) => { let _ = (); (~y) => x+y } +// This looks too far into the return type +let d = foo(. ~y=3) diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index d36bb7ef25..bdab5bda28 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -2021,9 +2021,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); unify_var env (newvar()) funct.exp_type; - let mk_exp exp_desc exp_type = + let mk_exp ?(loc=Location.none) exp_desc exp_type = { exp_desc; - exp_loc = Location.none; exp_extra = []; + exp_loc = loc; exp_extra = []; exp_type; exp_attributes = []; exp_env = env } in @@ -2031,7 +2031,7 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in let (path, desc) = Env.lookup_value lid env in let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in - mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + mk_exp ~loc:e.exp_loc (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in let mk_apply funct args = rue { @@ -2999,8 +2999,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex if List.length sargs > arity then raise(Error(funct.exp_loc, env, Uncurried_arity_mismatch (t, arity, List.length sargs, false))); - t1 - | None -> t in + t1, arity + | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> @@ -3016,7 +3016,7 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (fully_applied, newT) | _ -> (false, newT) in - let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) + let rec type_unknown_args max_arity (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = match syntax_args with | [] -> @@ -3028,15 +3028,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | (l1, sarg1) :: sargl -> let (ty1, ty2) = let ty_fun = expand_head env ty_fun in + let arity_ok = List.length args < max_arity in match ty_fun.desc with - Tvar _ -> + Tvar _ -> let t1 = newvar () and t2 = newvar () in if ty_fun.level >= t1.level && not_identity funct.exp_desc then Location.prerr_warning sarg1.pexp_loc Warnings.Unused_argument; unify env ty_fun (newty (Tarrow(l1,t1,t2,Clink(ref Cunknown)))); (t1, t2) - | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 + | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> + if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -3044,6 +3046,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex let ty_res = result_type (omitted @ !ignored) ty_fun in match ty_res.desc with Tarrow _ -> + if not arity_ok then + raise (Error(sarg1.pexp_loc, env, + Apply_wrong_label(l1, funct.exp_type))) else if (not (has_label l1 ty_fun)) then raise (Error(sarg1.pexp_loc, env, Apply_wrong_label(l1, ty_res))) @@ -3060,13 +3065,13 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex unify_exp env arg1 (type_option(newvar())); arg1 in - type_unknown_args ((l1, Some arg1) :: args) omitted ty2 sargl + type_unknown_args max_arity ((l1, Some arg1) :: args) omitted ty2 sargl in - let rec type_args args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = + let rec type_args max_arity args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = match expand_head env ty_fun, expand_head env ty_fun0 with {desc=Tarrow (l, ty, ty_fun, com); level=lv} , {desc=Tarrow (_, ty0, ty_fun0, _)} - when (sargs <> [] ) && commu_repr com = Cok -> + when (sargs <> [] ) && commu_repr com = Cok && List.length args < max_arity -> let name = label_name l and optional = is_optional l in let sargs, omitted, arg = @@ -3091,9 +3096,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (extract_option_type env ty) (extract_option_type env ty0)))) in - type_args ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs + type_args max_arity ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs | _ -> - type_unknown_args args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) + type_unknown_args max_arity args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) in let () = let ls, tvar = list_labels env funct.exp_type in @@ -3126,8 +3131,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex ([Nolabel, Some exp], ty_res, false) | _ -> if uncurried then force_uncurried_type funct; - let ty = extract_uncurried_type funct.exp_type in - let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in + let ty, max_arity = extract_uncurried_type funct.exp_type in + let targs, ret_t = type_args max_arity [] [] ~ty_fun:ty (instance env ty) ~sargs in let fully_applied, ret_t = update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in targs, ret_t, fully_applied diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 2ee1fdeef5..1f132a3d8b 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -42751,9 +42751,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); unify_var env (newvar()) funct.exp_type; - let mk_exp exp_desc exp_type = + let mk_exp ?(loc=Location.none) exp_desc exp_type = { exp_desc; - exp_loc = Location.none; exp_extra = []; + exp_loc = loc; exp_extra = []; exp_type; exp_attributes = []; exp_env = env } in @@ -42761,7 +42761,7 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in let (path, desc) = Env.lookup_value lid env in let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in - mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + mk_exp ~loc:e.exp_loc (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in let mk_apply funct args = rue { @@ -43729,8 +43729,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex if List.length sargs > arity then raise(Error(funct.exp_loc, env, Uncurried_arity_mismatch (t, arity, List.length sargs, false))); - t1 - | None -> t in + t1, arity + | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> @@ -43746,7 +43746,7 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (fully_applied, newT) | _ -> (false, newT) in - let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) + let rec type_unknown_args max_arity (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = match syntax_args with | [] -> @@ -43758,15 +43758,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | (l1, sarg1) :: sargl -> let (ty1, ty2) = let ty_fun = expand_head env ty_fun in + let arity_ok = List.length args < max_arity in match ty_fun.desc with - Tvar _ -> + Tvar _ -> let t1 = newvar () and t2 = newvar () in if ty_fun.level >= t1.level && not_identity funct.exp_desc then Location.prerr_warning sarg1.pexp_loc Warnings.Unused_argument; unify env ty_fun (newty (Tarrow(l1,t1,t2,Clink(ref Cunknown)))); (t1, t2) - | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 + | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> + if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -43774,6 +43776,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex let ty_res = result_type (omitted @ !ignored) ty_fun in match ty_res.desc with Tarrow _ -> + if not arity_ok then + raise (Error(sarg1.pexp_loc, env, + Apply_wrong_label(l1, funct.exp_type))) else if (not (has_label l1 ty_fun)) then raise (Error(sarg1.pexp_loc, env, Apply_wrong_label(l1, ty_res))) @@ -43790,13 +43795,13 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex unify_exp env arg1 (type_option(newvar())); arg1 in - type_unknown_args ((l1, Some arg1) :: args) omitted ty2 sargl + type_unknown_args max_arity ((l1, Some arg1) :: args) omitted ty2 sargl in - let rec type_args args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = + let rec type_args max_arity args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = match expand_head env ty_fun, expand_head env ty_fun0 with {desc=Tarrow (l, ty, ty_fun, com); level=lv} , {desc=Tarrow (_, ty0, ty_fun0, _)} - when (sargs <> [] ) && commu_repr com = Cok -> + when (sargs <> [] ) && commu_repr com = Cok && List.length args < max_arity -> let name = label_name l and optional = is_optional l in let sargs, omitted, arg = @@ -43821,9 +43826,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (extract_option_type env ty) (extract_option_type env ty0)))) in - type_args ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs + type_args max_arity ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs | _ -> - type_unknown_args args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) + type_unknown_args max_arity args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) in let () = let ls, tvar = list_labels env funct.exp_type in @@ -43856,8 +43861,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex ([Nolabel, Some exp], ty_res, false) | _ -> if uncurried then force_uncurried_type funct; - let ty = extract_uncurried_type funct.exp_type in - let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in + let ty, max_arity = extract_uncurried_type funct.exp_type in + let targs, ret_t = type_args max_arity [] [] ~ty_fun:ty (instance env ty) ~sargs in let fully_applied, ret_t = update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in targs, ret_t, fully_applied diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index 8469cfbb3b..ef7ef38a2f 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -42751,9 +42751,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); unify_var env (newvar()) funct.exp_type; - let mk_exp exp_desc exp_type = + let mk_exp ?(loc=Location.none) exp_desc exp_type = { exp_desc; - exp_loc = Location.none; exp_extra = []; + exp_loc = loc; exp_extra = []; exp_type; exp_attributes = []; exp_env = env } in @@ -42761,7 +42761,7 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in let (path, desc) = Env.lookup_value lid env in let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in - mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + mk_exp ~loc:e.exp_loc (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in let mk_apply funct args = rue { @@ -43729,8 +43729,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex if List.length sargs > arity then raise(Error(funct.exp_loc, env, Uncurried_arity_mismatch (t, arity, List.length sargs, false))); - t1 - | None -> t in + t1, arity + | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> @@ -43746,7 +43746,7 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (fully_applied, newT) | _ -> (false, newT) in - let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) + let rec type_unknown_args max_arity (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = match syntax_args with | [] -> @@ -43758,15 +43758,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | (l1, sarg1) :: sargl -> let (ty1, ty2) = let ty_fun = expand_head env ty_fun in + let arity_ok = List.length args < max_arity in match ty_fun.desc with - Tvar _ -> + Tvar _ -> let t1 = newvar () and t2 = newvar () in if ty_fun.level >= t1.level && not_identity funct.exp_desc then Location.prerr_warning sarg1.pexp_loc Warnings.Unused_argument; unify env ty_fun (newty (Tarrow(l1,t1,t2,Clink(ref Cunknown)))); (t1, t2) - | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 + | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> + if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -43774,6 +43776,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex let ty_res = result_type (omitted @ !ignored) ty_fun in match ty_res.desc with Tarrow _ -> + if not arity_ok then + raise (Error(sarg1.pexp_loc, env, + Apply_wrong_label(l1, funct.exp_type))) else if (not (has_label l1 ty_fun)) then raise (Error(sarg1.pexp_loc, env, Apply_wrong_label(l1, ty_res))) @@ -43790,13 +43795,13 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex unify_exp env arg1 (type_option(newvar())); arg1 in - type_unknown_args ((l1, Some arg1) :: args) omitted ty2 sargl + type_unknown_args max_arity ((l1, Some arg1) :: args) omitted ty2 sargl in - let rec type_args args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = + let rec type_args max_arity args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = match expand_head env ty_fun, expand_head env ty_fun0 with {desc=Tarrow (l, ty, ty_fun, com); level=lv} , {desc=Tarrow (_, ty0, ty_fun0, _)} - when (sargs <> [] ) && commu_repr com = Cok -> + when (sargs <> [] ) && commu_repr com = Cok && List.length args < max_arity -> let name = label_name l and optional = is_optional l in let sargs, omitted, arg = @@ -43821,9 +43826,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (extract_option_type env ty) (extract_option_type env ty0)))) in - type_args ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs + type_args max_arity ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs | _ -> - type_unknown_args args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) + type_unknown_args max_arity args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) in let () = let ls, tvar = list_labels env funct.exp_type in @@ -43856,8 +43861,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex ([Nolabel, Some exp], ty_res, false) | _ -> if uncurried then force_uncurried_type funct; - let ty = extract_uncurried_type funct.exp_type in - let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in + let ty, max_arity = extract_uncurried_type funct.exp_type in + let targs, ret_t = type_args max_arity [] [] ~ty_fun:ty (instance env ty) ~sargs in let fully_applied, ret_t = update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in targs, ret_t, fully_applied diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index e6e418274c..0eaf132ec4 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -97749,9 +97749,9 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = end_def (); unify_var env (newvar()) funct.exp_type; - let mk_exp exp_desc exp_type = + let mk_exp ?(loc=Location.none) exp_desc exp_type = { exp_desc; - exp_loc = Location.none; exp_extra = []; + exp_loc = loc; exp_extra = []; exp_type; exp_attributes = []; exp_env = env } in @@ -97759,7 +97759,7 @@ and type_expect_ ?in_function ?(recarg=Rejected) env sexp ty_expected = let lid:Longident.t = Ldot (Ldot (Lident "Js", "Internal"), name) in let (path, desc) = Env.lookup_value lid env in let id = mk_exp (Texp_ident(path, {txt=lid; loc=Location.none}, desc)) desc.val_type in - mk_exp (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in + mk_exp ~loc:e.exp_loc (Texp_apply(id, [(Nolabel, Some e)])) e.exp_type in let mk_apply funct args = rue { @@ -98727,8 +98727,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex if List.length sargs > arity then raise(Error(funct.exp_loc, env, Uncurried_arity_mismatch (t, arity, List.length sargs, false))); - t1 - | None -> t in + t1, arity + | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> @@ -98744,7 +98744,7 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (fully_applied, newT) | _ -> (false, newT) in - let rec type_unknown_args (args : lazy_args) omitted ty_fun (syntax_args : sargs) + let rec type_unknown_args max_arity (args : lazy_args) omitted ty_fun (syntax_args : sargs) : targs * _ = match syntax_args with | [] -> @@ -98756,15 +98756,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | (l1, sarg1) :: sargl -> let (ty1, ty2) = let ty_fun = expand_head env ty_fun in + let arity_ok = List.length args < max_arity in match ty_fun.desc with - Tvar _ -> + Tvar _ -> let t1 = newvar () and t2 = newvar () in if ty_fun.level >= t1.level && not_identity funct.exp_desc then Location.prerr_warning sarg1.pexp_loc Warnings.Unused_argument; unify env ty_fun (newty (Tarrow(l1,t1,t2,Clink(ref Cunknown)))); (t1, t2) - | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 + | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> + if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -98772,6 +98774,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex let ty_res = result_type (omitted @ !ignored) ty_fun in match ty_res.desc with Tarrow _ -> + if not arity_ok then + raise (Error(sarg1.pexp_loc, env, + Apply_wrong_label(l1, funct.exp_type))) else if (not (has_label l1 ty_fun)) then raise (Error(sarg1.pexp_loc, env, Apply_wrong_label(l1, ty_res))) @@ -98788,13 +98793,13 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex unify_exp env arg1 (type_option(newvar())); arg1 in - type_unknown_args ((l1, Some arg1) :: args) omitted ty2 sargl + type_unknown_args max_arity ((l1, Some arg1) :: args) omitted ty2 sargl in - let rec type_args args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = + let rec type_args max_arity args omitted ~ty_fun ty_fun0 ~(sargs : sargs) = match expand_head env ty_fun, expand_head env ty_fun0 with {desc=Tarrow (l, ty, ty_fun, com); level=lv} , {desc=Tarrow (_, ty0, ty_fun0, _)} - when (sargs <> [] ) && commu_repr com = Cok -> + when (sargs <> [] ) && commu_repr com = Cok && List.length args < max_arity -> let name = label_name l and optional = is_optional l in let sargs, omitted, arg = @@ -98819,9 +98824,9 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (extract_option_type env ty) (extract_option_type env ty0)))) in - type_args ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs + type_args max_arity ((l,arg)::args) omitted ~ty_fun ty_fun0 ~sargs | _ -> - type_unknown_args args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) + type_unknown_args max_arity args omitted ty_fun0 sargs (* This is the hot path for non-labeled function*) in let () = let ls, tvar = list_labels env funct.exp_type in @@ -98854,8 +98859,8 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex ([Nolabel, Some exp], ty_res, false) | _ -> if uncurried then force_uncurried_type funct; - let ty = extract_uncurried_type funct.exp_type in - let targs, ret_t = type_args [] [] ~ty_fun:ty (instance env ty) ~sargs in + let ty, max_arity = extract_uncurried_type funct.exp_type in + let targs, ret_t = type_args max_arity [] [] ~ty_fun:ty (instance env ty) ~sargs in let fully_applied, ret_t = update_uncurried_arity funct.exp_type ~nargs:(List.length !ignored + List.length sargs) ret_t in targs, ret_t, fully_applied From 094e62a6043bea6de5ad88d1658735657516a3ae Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 23 Nov 2022 11:13:25 +0100 Subject: [PATCH 3/6] clean up error message that is now not possible --- jscomp/ml/typecore.ml | 17 ++++------------- jscomp/ml/typecore.mli | 2 +- lib/4.06.1/unstable/js_compiler.ml | 19 +++++-------------- lib/4.06.1/unstable/js_playground_compiler.ml | 19 +++++-------------- lib/4.06.1/whole_compiler.ml | 19 +++++-------------- 5 files changed, 20 insertions(+), 56 deletions(-) diff --git a/jscomp/ml/typecore.ml b/jscomp/ml/typecore.ml index bdab5bda28..62e5cd9f6b 100644 --- a/jscomp/ml/typecore.ml +++ b/jscomp/ml/typecore.ml @@ -73,7 +73,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -2998,20 +2998,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | Some (arity, t1) -> if List.length sargs > arity then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); t1, arity | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> let newarity = arity - nargs in - if newarity < 0 then - raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, true))); let fully_applied = newarity = 0 in if uncurried && not fully_applied then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); let newT = if fully_applied then newT else mk_js_fn newarity newT in (fully_applied, newT) | _ -> (false, newT) @@ -3038,7 +3035,6 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (t1, t2) | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> - if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -3871,16 +3867,11 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." - | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + | Uncurried_arity_mismatch (typ, arity, args) -> fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" type_expr typ; fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" args (if args = 0 then "" else "s") arity - | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> - fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" - type_expr typ; - fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" - let super_report_error_no_wrap_printing_env = report_error diff --git a/jscomp/ml/typecore.mli b/jscomp/ml/typecore.mli index 49918ecf6f..f80f9584ba 100644 --- a/jscomp/ml/typecore.mli +++ b/jscomp/ml/typecore.mli @@ -109,7 +109,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 1f132a3d8b..716dad3f82 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -40695,7 +40695,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -40803,7 +40803,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -43728,20 +43728,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | Some (arity, t1) -> if List.length sargs > arity then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); t1, arity | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> let newarity = arity - nargs in - if newarity < 0 then - raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, true))); let fully_applied = newarity = 0 in if uncurried && not fully_applied then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); let newT = if fully_applied then newT else mk_js_fn newarity newT in (fully_applied, newT) | _ -> (false, newT) @@ -43768,7 +43765,6 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (t1, t2) | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> - if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -44601,16 +44597,11 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." - | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + | Uncurried_arity_mismatch (typ, arity, args) -> fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" type_expr typ; fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" args (if args = 0 then "" else "s") arity - | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> - fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" - type_expr typ; - fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" - let super_report_error_no_wrap_printing_env = report_error diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index ef7ef38a2f..8c9d6cc1c5 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -40695,7 +40695,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -40803,7 +40803,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -43728,20 +43728,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | Some (arity, t1) -> if List.length sargs > arity then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); t1, arity | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> let newarity = arity - nargs in - if newarity < 0 then - raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, true))); let fully_applied = newarity = 0 in if uncurried && not fully_applied then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); let newT = if fully_applied then newT else mk_js_fn newarity newT in (fully_applied, newT) | _ -> (false, newT) @@ -43768,7 +43765,6 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (t1, t2) | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> - if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -44601,16 +44597,11 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." - | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + | Uncurried_arity_mismatch (typ, arity, args) -> fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" type_expr typ; fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" args (if args = 0 then "" else "s") arity - | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> - fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" - type_expr typ; - fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" - let super_report_error_no_wrap_printing_env = report_error diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index 0eaf132ec4..b09f4bf26e 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -95693,7 +95693,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -95801,7 +95801,7 @@ type error = | Illegal_letrec_pat | Labels_omitted of string list | Empty_record_literal - | Uncurried_arity_mismatch of type_expr * int * int * bool + | Uncurried_arity_mismatch of type_expr * int * int exception Error of Location.t * Env.t * error exception Error_forward of Location.error @@ -98726,20 +98726,17 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex | Some (arity, t1) -> if List.length sargs > arity then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); t1, arity | None -> t, max_int in let update_uncurried_arity ~nargs t newT = match has_uncurried_type t with | Some (arity, _) -> let newarity = arity - nargs in - if newarity < 0 then - raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, true))); let fully_applied = newarity = 0 in if uncurried && not fully_applied then raise(Error(funct.exp_loc, env, - Uncurried_arity_mismatch (t, arity, List.length sargs, false))); + Uncurried_arity_mismatch (t, arity, List.length sargs))); let newT = if fully_applied then newT else mk_js_fn newarity newT in (fully_applied, newT) | _ -> (false, newT) @@ -98766,7 +98763,6 @@ and type_application uncurried env funct (sargs : sargs) : targs * Types.type_ex (t1, t2) | Tarrow (l,t1,t2,_) when Asttypes.same_arg_label l l1 && arity_ok -> - if List.length args >= max_arity then assert false; (t1, t2) | td -> let ty_fun = @@ -99599,16 +99595,11 @@ let report_error env ppf = function (String.concat ", " labels) | Empty_record_literal -> fprintf ppf "Empty record literal {} should be type annotated or used in a record context." - | Uncurried_arity_mismatch (typ, arity, args, false (* no partial application *)) -> + | Uncurried_arity_mismatch (typ, arity, args) -> fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" type_expr typ; fprintf ppf "@ @[It is applied with @{%d@} argument%s but it requires @{%d@}.@]@]" args (if args = 0 then "" else "s") arity - | Uncurried_arity_mismatch (typ, _, _, true (* partial application *)) -> - fprintf ppf "@[@[<2>This uncurried function has type@ %a@]" - type_expr typ; - fprintf ppf "@ @[It is partially applied with too many arguments.@]@]" - let super_report_error_no_wrap_printing_env = report_error From 104fcbfee03f63afa4e297dc4e5903192e99fa03 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 23 Nov 2022 11:34:29 +0100 Subject: [PATCH 4/6] Add examples of uncurried functions with default arguments. --- jscomp/test/build.ninja | 3 +- jscomp/test/uncurried_default.args.js | 53 ++++++++++++++++++++++++++ jscomp/test/uncurried_default.args.res | 15 ++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 jscomp/test/uncurried_default.args.js create mode 100644 jscomp/test/uncurried_default.args.res diff --git a/jscomp/test/build.ninja b/jscomp/test/build.ninja index 66a5f283f9..399b813a52 100644 --- a/jscomp/test/build.ninja +++ b/jscomp/test/build.ninja @@ -718,6 +718,7 @@ o test/unboxed_crash.cmi test/unboxed_crash.cmj : cc test/unboxed_crash.ml | $bs o test/unboxed_use_case.cmj : cc_cmi test/unboxed_use_case.ml | test/unboxed_use_case.cmi $bsc $stdlib runtime o test/unboxed_use_case.cmi : cc test/unboxed_use_case.mli | $bsc $stdlib runtime o test/uncurried_cast.cmi test/uncurried_cast.cmj : cc test/uncurried_cast.res | $bsc $stdlib runtime +o test/uncurried_default.args.cmi test/uncurried_default.args.cmj : cc test/uncurried_default.args.res | $bsc $stdlib runtime o test/uncurried_pipe.cmi test/uncurried_pipe.cmj : cc test/uncurried_pipe.res | $bsc $stdlib runtime o test/uncurry_external_test.cmi test/uncurry_external_test.cmj : cc test/uncurry_external_test.ml | test/mt.cmj $bsc $stdlib runtime o test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj : cc test/uncurry_glob_test.ml | $bsc $stdlib runtime @@ -740,4 +741,4 @@ o test/utf8_decode_test.cmi test/utf8_decode_test.cmj : cc test/utf8_decode_test o test/variant.cmi test/variant.cmj : cc test/variant.ml | $bsc $stdlib runtime o test/watch_test.cmi test/watch_test.cmj : cc test/watch_test.ml | $bsc $stdlib runtime o test/webpack_config.cmi test/webpack_config.cmj : cc test/webpack_config.ml | $bsc $stdlib runtime -o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/SafePromises.cmi test/SafePromises.cmj test/UncurriedExternals.cmi test/UncurriedExternals.cmj test/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/app_root_finder.cmi test/app_root_finder.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/arity_ml.cmi test/arity_ml.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/array_test.cmi test/array_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_js_mapper_poly_test.cmi test/ast_js_mapper_poly_test.cmj test/ast_js_mapper_test.cmi test/ast_js_mapper_test.cmj test/ast_mapper_defensive_test.cmi test/ast_mapper_defensive_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_ideas.cmi test/async_ideas.cmj test/async_inline.cmi test/async_inline.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_node_string_buffer_test.cmi test/bs_node_string_buffer_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/caml_format_test.cmi test/caml_format_test.cmj test/caml_sys_poly_fill_test.cmi test/caml_sys_poly_fill_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_setter_getter.cmi test/class_setter_getter.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/config2_test.cmi test/config2_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo.cmi test/demo.cmj test/demo_binding.cmi test/demo_binding.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_test.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_def.cmi test/exception_def.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebind_test.cmi test/exception_rebind_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_repr_test.cmi test/exception_repr_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exn_error_pattern.cmi test/exn_error_pattern.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/flow_parser_reg_test.cmi test/flow_parser_reg_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/format_test.cmi test/format_test.cmj test/fs_test.cmi test/fs_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/genlex_test.cmi test/genlex_test.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1063_test.cmi test/gpr_1063_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1154_test.cmi test/gpr_1154_test.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1501_test.cmi test/gpr_1501_test.cmj test/gpr_1503_test.cmi test/gpr_1503_test.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1600_test.cmi test/gpr_1600_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2652_test.cmi test/gpr_2652_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_405_test.cmi test/gpr_405_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5312.cmi test/gpr_5312.cmj test/gpr_5557.cmi test/gpr_5557.cmj test/gpr_5753.cmi test/gpr_5753.cmj test/gpr_627_test.cmi test/gpr_627_test.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hamming_test.cmi test/hamming_test.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hashtbl_test.cmi test/hashtbl_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/http_types.cmi test/http_types.cmj test/ignore_test.cmi test/ignore_test.cmj test/imm_map_bench.cmi test/imm_map_bench.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/io_test.cmi test/io_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_list_test.cmi test/js_list_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_promise_basic_test.cmi test/js_promise_basic_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lexer_test.cmi test/lexer_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.cmj test/list_test.cmi test/list_test.cmj test/local_class_type.cmi test/local_class_type.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.cmj test/method_chain.cmi test/method_chain.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_fs_test.cmi test/node_fs_test.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/oo_js_test_date.cmi test/oo_js_test_date.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_type.cmi test/poly_type.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/ppx_this_obj_field.cmi test/ppx_this_obj_field.cmj test/ppx_this_obj_test.cmi test/ppx_this_obj_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/promise.cmi test/promise.cmj test/promise_catch_test.cmi test/promise_catch_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/rec_value_test.cmi test/rec_value_test.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_gen.cmi test/set_gen.cmj test/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simple_lexer_test.cmi test/simple_lexer_test.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_get_set_test.cmi test/string_get_set_test.cmj test/string_interp_test.cmi test/string_interp_test.cmj test/string_literal_print_test.cmi test/string_literal_print_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_filename.cmi test/test_filename.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_global_print.cmi test/test_global_print.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_http_server.cmi test/test_http_server.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_index.cmi test/test_index.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_internalOO.cmi test/test_internalOO.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_obj_simple_ffi.cmi test/test_obj_simple_ffi.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_promise_bind.cmi test/test_promise_bind.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_require.cmi test/test_require.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_unsupported_primitive.cmi test/test_unsupported_primitive.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/ui_defs.cmi test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurried_cast.cmi test/uncurried_cast.cmj test/uncurried_pipe.cmi test/uncurried_pipe.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_method.cmi test/uncurry_method.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_obj_external.cmi test/unsafe_obj_external.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/unsafe_this.cmi test/unsafe_this.cmj test/update_record_test.cmi test/update_record_test.cmj test/utf8_decode_test.cmi test/utf8_decode_test.cmj test/variant.cmi test/variant.cmj test/watch_test.cmi test/watch_test.cmj test/webpack_config.cmi test/webpack_config.cmj +o test : phony test/406_primitive_test.cmi test/406_primitive_test.cmj test/EmptyRecord.cmi test/EmptyRecord.cmj test/SafePromises.cmi test/SafePromises.cmj test/UncurriedExternals.cmi test/UncurriedExternals.cmj test/a.cmi test/a.cmj test/a_filename_test.cmi test/a_filename_test.cmj test/a_list_test.cmi test/a_list_test.cmj test/a_recursive_type.cmi test/a_recursive_type.cmj test/a_scope_bug.cmi test/a_scope_bug.cmj test/a_string_test.cmi test/a_string_test.cmj test/abstract_type.cmi test/abstract_type.cmj test/adt_optimize_test.cmi test/adt_optimize_test.cmj test/alias_test.cmi test/alias_test.cmj test/and_or_tailcall_test.cmi test/and_or_tailcall_test.cmj test/app_root_finder.cmi test/app_root_finder.cmj test/argv_test.cmi test/argv_test.cmj test/ari_regress_test.cmi test/ari_regress_test.cmj test/arith_lexer.cmi test/arith_lexer.cmj test/arith_parser.cmi test/arith_parser.cmj test/arith_syntax.cmi test/arith_syntax.cmj test/arity.cmi test/arity.cmj test/arity_deopt.cmi test/arity_deopt.cmj test/arity_infer.cmi test/arity_infer.cmj test/arity_ml.cmi test/arity_ml.cmj test/array_data_util.cmi test/array_data_util.cmj test/array_safe_get.cmi test/array_safe_get.cmj test/array_subtle_test.cmi test/array_subtle_test.cmj test/array_test.cmi test/array_test.cmj test/ast_abstract_test.cmi test/ast_abstract_test.cmj test/ast_js_mapper_poly_test.cmi test/ast_js_mapper_poly_test.cmj test/ast_js_mapper_test.cmi test/ast_js_mapper_test.cmj test/ast_mapper_defensive_test.cmi test/ast_mapper_defensive_test.cmj test/ast_mapper_unused_warning_test.cmi test/ast_mapper_unused_warning_test.cmj test/async_ideas.cmi test/async_ideas.cmj test/async_inline.cmi test/async_inline.cmj test/attr_test.cmi test/attr_test.cmj test/b.cmi test/b.cmj test/bal_set_mini.cmi test/bal_set_mini.cmj test/bang_primitive.cmi test/bang_primitive.cmj test/basic_module_test.cmi test/basic_module_test.cmj test/bb.cmi test/bb.cmj test/bdd.cmi test/bdd.cmj test/belt_internal_test.cmi test/belt_internal_test.cmj test/belt_result_alias_test.cmi test/belt_result_alias_test.cmj test/bench.cmi test/bench.cmj test/big_enum.cmi test/big_enum.cmj test/big_polyvar_test.cmi test/big_polyvar_test.cmj test/block_alias_test.cmi test/block_alias_test.cmj test/boolean_test.cmi test/boolean_test.cmj test/bs_MapInt_test.cmi test/bs_MapInt_test.cmj test/bs_abstract_test.cmi test/bs_abstract_test.cmj test/bs_array_test.cmi test/bs_array_test.cmj test/bs_auto_uncurry.cmi test/bs_auto_uncurry.cmj test/bs_auto_uncurry_test.cmi test/bs_auto_uncurry_test.cmj test/bs_float_test.cmi test/bs_float_test.cmj test/bs_hashmap_test.cmi test/bs_hashmap_test.cmj test/bs_hashset_int_test.cmi test/bs_hashset_int_test.cmj test/bs_hashtbl_string_test.cmi test/bs_hashtbl_string_test.cmj test/bs_ignore_effect.cmi test/bs_ignore_effect.cmj test/bs_ignore_test.cmi test/bs_ignore_test.cmj test/bs_int_test.cmi test/bs_int_test.cmj test/bs_list_test.cmi test/bs_list_test.cmj test/bs_map_set_dict_test.cmi test/bs_map_set_dict_test.cmj test/bs_map_test.cmi test/bs_map_test.cmj test/bs_min_max_test.cmi test/bs_min_max_test.cmj test/bs_mutable_set_test.cmi test/bs_mutable_set_test.cmj test/bs_node_string_buffer_test.cmi test/bs_node_string_buffer_test.cmj test/bs_poly_map_test.cmi test/bs_poly_map_test.cmj test/bs_poly_mutable_map_test.cmi test/bs_poly_mutable_map_test.cmj test/bs_poly_mutable_set_test.cmi test/bs_poly_mutable_set_test.cmj test/bs_poly_set_test.cmi test/bs_poly_set_test.cmj test/bs_qualified.cmi test/bs_qualified.cmj test/bs_queue_test.cmi test/bs_queue_test.cmj test/bs_rbset_int_bench.cmi test/bs_rbset_int_bench.cmj test/bs_rest_test.cmi test/bs_rest_test.cmj test/bs_set_bench.cmi test/bs_set_bench.cmj test/bs_set_int_test.cmi test/bs_set_int_test.cmj test/bs_sort_test.cmi test/bs_sort_test.cmj test/bs_splice_partial.cmi test/bs_splice_partial.cmj test/bs_stack_test.cmi test/bs_stack_test.cmj test/bs_string_test.cmi test/bs_string_test.cmj test/bs_unwrap_test.cmi test/bs_unwrap_test.cmj test/buffer_test.cmi test/buffer_test.cmj test/bytes_split_gpr_743_test.cmi test/bytes_split_gpr_743_test.cmj test/caml_compare_test.cmi test/caml_compare_test.cmj test/caml_format_test.cmi test/caml_format_test.cmj test/caml_sys_poly_fill_test.cmi test/caml_sys_poly_fill_test.cmj test/chain_code_test.cmi test/chain_code_test.cmj test/chn_test.cmi test/chn_test.cmj test/class_setter_getter.cmi test/class_setter_getter.cmj test/class_type_ffi_test.cmi test/class_type_ffi_test.cmj test/coercion_module_alias_test.cmi test/coercion_module_alias_test.cmj test/compare_test.cmi test/compare_test.cmj test/complete_parmatch_test.cmi test/complete_parmatch_test.cmj test/complex_if_test.cmi test/complex_if_test.cmj test/complex_test.cmi test/complex_test.cmj test/complex_while_loop.cmi test/complex_while_loop.cmj test/condition_compilation_test.cmi test/condition_compilation_test.cmj test/config1_test.cmi test/config1_test.cmj test/config2_test.cmi test/config2_test.cmj test/console_log_test.cmi test/console_log_test.cmj test/const_block_test.cmi test/const_block_test.cmj test/const_defs.cmi test/const_defs.cmj test/const_defs_test.cmi test/const_defs_test.cmj test/const_test.cmi test/const_test.cmj test/cont_int_fold_test.cmi test/cont_int_fold_test.cmj test/cps_test.cmi test/cps_test.cmj test/cross_module_inline_test.cmi test/cross_module_inline_test.cmj test/custom_error_test.cmi test/custom_error_test.cmj test/debug_keep_test.cmi test/debug_keep_test.cmj test/debug_mode_value.cmi test/debug_mode_value.cmj test/debug_tmp.cmi test/debug_tmp.cmj test/debugger_test.cmi test/debugger_test.cmj test/default_export_test.cmi test/default_export_test.cmj test/defunctor_make_test.cmi test/defunctor_make_test.cmj test/demo.cmi test/demo.cmj test/demo_binding.cmi test/demo_binding.cmj test/demo_int_map.cmi test/demo_int_map.cmj test/demo_page.cmi test/demo_page.cmj test/demo_pipe.cmi test/demo_pipe.cmj test/derive_dyntype.cmi test/derive_dyntype.cmj test/derive_projector_test.cmi test/derive_projector_test.cmj test/derive_type_test.cmi test/derive_type_test.cmj test/digest_test.cmi test/digest_test.cmj test/div_by_zero_test.cmi test/div_by_zero_test.cmj test/dollar_escape_test.cmi test/dollar_escape_test.cmj test/earger_curry_test.cmi test/earger_curry_test.cmj test/effect.cmi test/effect.cmj test/epsilon_test.cmi test/epsilon_test.cmj test/equal_box_test.cmi test/equal_box_test.cmj test/equal_exception_test.cmi test/equal_exception_test.cmj test/equal_test.cmi test/equal_test.cmj test/es6_export.cmi test/es6_export.cmj test/es6_import.cmi test/es6_import.cmj test/es6_module_test.cmi test/es6_module_test.cmj test/escape_esmodule.cmi test/escape_esmodule.cmj test/esmodule_ref.cmi test/esmodule_ref.cmj test/event_ffi.cmi test/event_ffi.cmj test/exception_alias.cmi test/exception_alias.cmj test/exception_def.cmi test/exception_def.cmj test/exception_raise_test.cmi test/exception_raise_test.cmj test/exception_rebind_test.cmi test/exception_rebind_test.cmj test/exception_rebound_err_test.cmi test/exception_rebound_err_test.cmj test/exception_repr_test.cmi test/exception_repr_test.cmj test/exception_value_test.cmi test/exception_value_test.cmj test/exn_error_pattern.cmi test/exn_error_pattern.cmj test/export_keyword.cmi test/export_keyword.cmj test/ext_array_test.cmi test/ext_array_test.cmj test/ext_bytes_test.cmi test/ext_bytes_test.cmj test/ext_filename_test.cmi test/ext_filename_test.cmj test/ext_list_test.cmi test/ext_list_test.cmj test/ext_pervasives_test.cmi test/ext_pervasives_test.cmj test/ext_string_test.cmi test/ext_string_test.cmj test/ext_sys_test.cmi test/ext_sys_test.cmj test/extensible_variant_test.cmi test/extensible_variant_test.cmj test/external_polyfill_test.cmi test/external_polyfill_test.cmj test/external_ppx.cmi test/external_ppx.cmj test/external_ppx2.cmi test/external_ppx2.cmj test/fail_comp.cmi test/fail_comp.cmj test/ffi_arity_test.cmi test/ffi_arity_test.cmj test/ffi_array_test.cmi test/ffi_array_test.cmj test/ffi_js_test.cmi test/ffi_js_test.cmj test/ffi_splice_test.cmi test/ffi_splice_test.cmj test/ffi_test.cmi test/ffi_test.cmj test/fib.cmi test/fib.cmj test/flattern_order_test.cmi test/flattern_order_test.cmj test/flexible_array_test.cmi test/flexible_array_test.cmj test/float_array.cmi test/float_array.cmj test/float_of_bits_test.cmi test/float_of_bits_test.cmj test/float_record.cmi test/float_record.cmj test/float_test.cmi test/float_test.cmj test/floatarray_test.cmi test/floatarray_test.cmj test/flow_parser_reg_test.cmi test/flow_parser_reg_test.cmj test/for_loop_test.cmi test/for_loop_test.cmj test/for_side_effect_test.cmi test/for_side_effect_test.cmj test/format_regression.cmi test/format_regression.cmj test/format_test.cmi test/format_test.cmj test/fs_test.cmi test/fs_test.cmj test/fun_pattern_match.cmi test/fun_pattern_match.cmj test/functor_app_test.cmi test/functor_app_test.cmj test/functor_def.cmi test/functor_def.cmj test/functor_ffi.cmi test/functor_ffi.cmj test/functor_inst.cmi test/functor_inst.cmj test/functors.cmi test/functors.cmj test/gbk.cmi test/gbk.cmj test/genlex_test.cmi test/genlex_test.cmj test/gentTypeReTest.cmi test/gentTypeReTest.cmj test/global_exception_regression_test.cmi test/global_exception_regression_test.cmj test/global_mangles.cmi test/global_mangles.cmj test/global_module_alias_test.cmi test/global_module_alias_test.cmj test/google_closure_test.cmi test/google_closure_test.cmj test/gpr496_test.cmi test/gpr496_test.cmj test/gpr_1063_test.cmi test/gpr_1063_test.cmj test/gpr_1072.cmi test/gpr_1072.cmj test/gpr_1072_reg.cmi test/gpr_1072_reg.cmj test/gpr_1150.cmi test/gpr_1150.cmj test/gpr_1154_test.cmi test/gpr_1154_test.cmj test/gpr_1170.cmi test/gpr_1170.cmj test/gpr_1240_missing_unbox.cmi test/gpr_1240_missing_unbox.cmj test/gpr_1245_test.cmi test/gpr_1245_test.cmj test/gpr_1268.cmi test/gpr_1268.cmj test/gpr_1409_test.cmi test/gpr_1409_test.cmj test/gpr_1423_app_test.cmi test/gpr_1423_app_test.cmj test/gpr_1423_nav.cmi test/gpr_1423_nav.cmj test/gpr_1438.cmi test/gpr_1438.cmj test/gpr_1481.cmi test/gpr_1481.cmj test/gpr_1484.cmi test/gpr_1484.cmj test/gpr_1501_test.cmi test/gpr_1501_test.cmj test/gpr_1503_test.cmi test/gpr_1503_test.cmj test/gpr_1539_test.cmi test/gpr_1539_test.cmj test/gpr_1600_test.cmi test/gpr_1600_test.cmj test/gpr_1658_test.cmi test/gpr_1658_test.cmj test/gpr_1667_test.cmi test/gpr_1667_test.cmj test/gpr_1692_test.cmi test/gpr_1692_test.cmj test/gpr_1698_test.cmi test/gpr_1698_test.cmj test/gpr_1701_test.cmi test/gpr_1701_test.cmj test/gpr_1716_test.cmi test/gpr_1716_test.cmj test/gpr_1717_test.cmi test/gpr_1717_test.cmj test/gpr_1728_test.cmi test/gpr_1728_test.cmj test/gpr_1749_test.cmi test/gpr_1749_test.cmj test/gpr_1759_test.cmi test/gpr_1759_test.cmj test/gpr_1760_test.cmi test/gpr_1760_test.cmj test/gpr_1762_test.cmi test/gpr_1762_test.cmj test/gpr_1817_test.cmi test/gpr_1817_test.cmj test/gpr_1822_test.cmi test/gpr_1822_test.cmj test/gpr_1891_test.cmi test/gpr_1891_test.cmj test/gpr_1943_test.cmi test/gpr_1943_test.cmj test/gpr_1946_test.cmi test/gpr_1946_test.cmj test/gpr_2316_test.cmi test/gpr_2316_test.cmj test/gpr_2352_test.cmi test/gpr_2352_test.cmj test/gpr_2413_test.cmi test/gpr_2413_test.cmj test/gpr_2474.cmi test/gpr_2474.cmj test/gpr_2487.cmi test/gpr_2487.cmj test/gpr_2503_test.cmi test/gpr_2503_test.cmj test/gpr_2608_test.cmi test/gpr_2608_test.cmj test/gpr_2614_test.cmi test/gpr_2614_test.cmj test/gpr_2633_test.cmi test/gpr_2633_test.cmj test/gpr_2642_test.cmi test/gpr_2642_test.cmj test/gpr_2652_test.cmi test/gpr_2652_test.cmj test/gpr_2682_test.cmi test/gpr_2682_test.cmj test/gpr_2700_test.cmi test/gpr_2700_test.cmj test/gpr_2731_test.cmi test/gpr_2731_test.cmj test/gpr_2789_test.cmi test/gpr_2789_test.cmj test/gpr_2931_test.cmi test/gpr_2931_test.cmj test/gpr_3142_test.cmi test/gpr_3142_test.cmj test/gpr_3154_test.cmi test/gpr_3154_test.cmj test/gpr_3209_test.cmi test/gpr_3209_test.cmj test/gpr_3492_test.cmi test/gpr_3492_test.cmj test/gpr_3519_jsx_test.cmi test/gpr_3519_jsx_test.cmj test/gpr_3519_test.cmi test/gpr_3519_test.cmj test/gpr_3536_test.cmi test/gpr_3536_test.cmj test/gpr_3546_test.cmi test/gpr_3546_test.cmj test/gpr_3548_test.cmi test/gpr_3548_test.cmj test/gpr_3549_test.cmi test/gpr_3549_test.cmj test/gpr_3566_drive_test.cmi test/gpr_3566_drive_test.cmj test/gpr_3566_test.cmi test/gpr_3566_test.cmj test/gpr_3595_test.cmi test/gpr_3595_test.cmj test/gpr_3609_test.cmi test/gpr_3609_test.cmj test/gpr_3697_test.cmi test/gpr_3697_test.cmj test/gpr_373_test.cmi test/gpr_373_test.cmj test/gpr_3770_test.cmi test/gpr_3770_test.cmj test/gpr_3852_alias.cmi test/gpr_3852_alias.cmj test/gpr_3852_alias_reify.cmi test/gpr_3852_alias_reify.cmj test/gpr_3852_effect.cmi test/gpr_3852_effect.cmj test/gpr_3865.cmi test/gpr_3865.cmj test/gpr_3865_bar.cmi test/gpr_3865_bar.cmj test/gpr_3865_foo.cmi test/gpr_3865_foo.cmj test/gpr_3875_test.cmi test/gpr_3875_test.cmj test/gpr_3877_test.cmi test/gpr_3877_test.cmj test/gpr_3895_test.cmi test/gpr_3895_test.cmj test/gpr_3897_test.cmi test/gpr_3897_test.cmj test/gpr_3931_test.cmi test/gpr_3931_test.cmj test/gpr_3980_test.cmi test/gpr_3980_test.cmj test/gpr_4025_test.cmi test/gpr_4025_test.cmj test/gpr_405_test.cmi test/gpr_405_test.cmj test/gpr_4069_test.cmi test/gpr_4069_test.cmj test/gpr_4265_test.cmi test/gpr_4265_test.cmj test/gpr_4274_test.cmi test/gpr_4274_test.cmj test/gpr_4280_test.cmi test/gpr_4280_test.cmj test/gpr_4407_test.cmi test/gpr_4407_test.cmj test/gpr_441.cmi test/gpr_441.cmj test/gpr_4442_test.cmi test/gpr_4442_test.cmj test/gpr_4491_test.cmi test/gpr_4491_test.cmj test/gpr_4494_test.cmi test/gpr_4494_test.cmj test/gpr_4519_test.cmi test/gpr_4519_test.cmj test/gpr_459_test.cmi test/gpr_459_test.cmj test/gpr_4632.cmi test/gpr_4632.cmj test/gpr_4639_test.cmi test/gpr_4639_test.cmj test/gpr_4900_test.cmi test/gpr_4900_test.cmj test/gpr_4924_test.cmi test/gpr_4924_test.cmj test/gpr_4931.cmi test/gpr_4931.cmj test/gpr_4931_allow.cmi test/gpr_4931_allow.cmj test/gpr_5071_test.cmi test/gpr_5071_test.cmj test/gpr_5169_test.cmi test/gpr_5169_test.cmj test/gpr_5218_test.cmi test/gpr_5218_test.cmj test/gpr_5280_optimize_test.cmi test/gpr_5280_optimize_test.cmj test/gpr_5312.cmi test/gpr_5312.cmj test/gpr_5557.cmi test/gpr_5557.cmj test/gpr_5753.cmi test/gpr_5753.cmj test/gpr_627_test.cmi test/gpr_627_test.cmj test/gpr_658.cmi test/gpr_658.cmj test/gpr_858_test.cmi test/gpr_858_test.cmj test/gpr_858_unit2_test.cmi test/gpr_858_unit2_test.cmj test/gpr_904_test.cmi test/gpr_904_test.cmj test/gpr_974_test.cmi test/gpr_974_test.cmj test/gpr_977_test.cmi test/gpr_977_test.cmj test/gpr_return_type_unused_attribute.cmi test/gpr_return_type_unused_attribute.cmj test/gray_code_test.cmi test/gray_code_test.cmj test/guide_for_ext.cmi test/guide_for_ext.cmj test/hamming_test.cmi test/hamming_test.cmj test/hash_collision_test.cmi test/hash_collision_test.cmj test/hash_sugar_desugar.cmi test/hash_sugar_desugar.cmj test/hash_test.cmi test/hash_test.cmj test/hashtbl_test.cmi test/hashtbl_test.cmj test/hello.foo.cmi test/hello.foo.cmj test/hello_res.cmi test/hello_res.cmj test/http_types.cmi test/http_types.cmj test/ignore_test.cmi test/ignore_test.cmj test/imm_map_bench.cmi test/imm_map_bench.cmj test/include_side_effect.cmi test/include_side_effect.cmj test/include_side_effect_free.cmi test/include_side_effect_free.cmj test/incomplete_toplevel_test.cmi test/incomplete_toplevel_test.cmj test/infer_type_test.cmi test/infer_type_test.cmj test/inline_const.cmi test/inline_const.cmj test/inline_const_test.cmi test/inline_const_test.cmj test/inline_edge_cases.cmi test/inline_edge_cases.cmj test/inline_map2_test.cmi test/inline_map2_test.cmj test/inline_map_demo.cmi test/inline_map_demo.cmj test/inline_map_test.cmi test/inline_map_test.cmj test/inline_record_test.cmi test/inline_record_test.cmj test/inline_regression_test.cmi test/inline_regression_test.cmj test/inline_string_test.cmi test/inline_string_test.cmj test/inner_call.cmi test/inner_call.cmj test/inner_define.cmi test/inner_define.cmj test/inner_unused.cmi test/inner_unused.cmj test/installation_test.cmi test/installation_test.cmj test/int32_test.cmi test/int32_test.cmj test/int64_mul_div_test.cmi test/int64_mul_div_test.cmj test/int64_string_bench.cmi test/int64_string_bench.cmj test/int64_string_test.cmi test/int64_string_test.cmj test/int64_test.cmi test/int64_test.cmj test/int_hashtbl_test.cmi test/int_hashtbl_test.cmj test/int_map.cmi test/int_map.cmj test/int_overflow_test.cmi test/int_overflow_test.cmj test/int_poly_var.cmi test/int_poly_var.cmj test/int_switch_test.cmi test/int_switch_test.cmj test/internal_unused_test.cmi test/internal_unused_test.cmj test/io_test.cmi test/io_test.cmj test/js_array_test.cmi test/js_array_test.cmj test/js_bool_test.cmi test/js_bool_test.cmj test/js_cast_test.cmi test/js_cast_test.cmj test/js_date_test.cmi test/js_date_test.cmj test/js_dict_test.cmi test/js_dict_test.cmj test/js_exception_catch_test.cmi test/js_exception_catch_test.cmj test/js_float_test.cmi test/js_float_test.cmj test/js_global_test.cmi test/js_global_test.cmj test/js_int_test.cmi test/js_int_test.cmj test/js_json_test.cmi test/js_json_test.cmj test/js_list_test.cmi test/js_list_test.cmj test/js_math_test.cmi test/js_math_test.cmj test/js_null_test.cmi test/js_null_test.cmj test/js_null_undefined_test.cmi test/js_null_undefined_test.cmj test/js_nullable_test.cmi test/js_nullable_test.cmj test/js_obj_test.cmi test/js_obj_test.cmj test/js_option_test.cmi test/js_option_test.cmj test/js_promise_basic_test.cmi test/js_promise_basic_test.cmj test/js_re_test.cmi test/js_re_test.cmj test/js_string_test.cmi test/js_string_test.cmj test/js_typed_array_test.cmi test/js_typed_array_test.cmj test/js_undefined_test.cmi test/js_undefined_test.cmj test/js_val.cmi test/js_val.cmj test/jsoo_400_test.cmi test/jsoo_400_test.cmj test/jsoo_485_test.cmi test/jsoo_485_test.cmj test/key_word_property.cmi test/key_word_property.cmj test/key_word_property2.cmi test/key_word_property2.cmj test/key_word_property_plus_test.cmi test/key_word_property_plus_test.cmj test/label_uncurry.cmi test/label_uncurry.cmj test/large_integer_pat.cmi test/large_integer_pat.cmj test/large_record_duplication_test.cmi test/large_record_duplication_test.cmj test/largest_int_flow.cmi test/largest_int_flow.cmj test/lazy_demo.cmi test/lazy_demo.cmj test/lazy_test.cmi test/lazy_test.cmj test/lexer_test.cmi test/lexer_test.cmj test/lib_js_test.cmi test/lib_js_test.cmj test/libarg_test.cmi test/libarg_test.cmj test/libqueue_test.cmi test/libqueue_test.cmj test/limits_test.cmi test/limits_test.cmj test/list_stack.cmi test/list_stack.cmj test/list_test.cmi test/list_test.cmj test/local_class_type.cmi test/local_class_type.cmj test/local_exception_test.cmi test/local_exception_test.cmj test/loop_regression_test.cmi test/loop_regression_test.cmj test/loop_suites_test.cmi test/loop_suites_test.cmj test/map_find_test.cmi test/map_find_test.cmj test/map_test.cmi test/map_test.cmj test/mario_game.cmi test/mario_game.cmj test/marshal.cmi test/marshal.cmj test/method_chain.cmi test/method_chain.cmj test/method_name_test.cmi test/method_name_test.cmj test/method_string_name.cmi test/method_string_name.cmj test/minimal_test.cmi test/minimal_test.cmj test/miss_colon_test.cmi test/miss_colon_test.cmj test/mock_mt.cmi test/mock_mt.cmj test/module_alias_test.cmi test/module_alias_test.cmj test/module_as_class_ffi.cmi test/module_as_class_ffi.cmj test/module_as_function.cmi test/module_as_function.cmj test/module_missing_conversion.cmi test/module_missing_conversion.cmj test/module_parameter_test.cmi test/module_parameter_test.cmj test/module_splice_test.cmi test/module_splice_test.cmj test/more_poly_variant_test.cmi test/more_poly_variant_test.cmj test/more_uncurry.cmi test/more_uncurry.cmj test/mpr_6033_test.cmi test/mpr_6033_test.cmj test/mt.cmi test/mt.cmj test/mt_global.cmi test/mt_global.cmj test/mutable_obj_test.cmi test/mutable_obj_test.cmj test/mutable_uncurry_test.cmi test/mutable_uncurry_test.cmj test/mutual_non_recursive_type.cmi test/mutual_non_recursive_type.cmj test/name_mangle_test.cmi test/name_mangle_test.cmj test/nested_include.cmi test/nested_include.cmj test/nested_module_alias.cmi test/nested_module_alias.cmj test/nested_obj_literal.cmi test/nested_obj_literal.cmj test/nested_obj_test.cmi test/nested_obj_test.cmj test/nested_pattern_match_test.cmi test/nested_pattern_match_test.cmj test/noassert.cmi test/noassert.cmj test/node_fs_test.cmi test/node_fs_test.cmj test/node_path_test.cmi test/node_path_test.cmj test/null_list_test.cmi test/null_list_test.cmj test/number_lexer.cmi test/number_lexer.cmj test/obj_literal_ppx.cmi test/obj_literal_ppx.cmj test/obj_literal_ppx_test.cmi test/obj_literal_ppx_test.cmj test/obj_magic_test.cmi test/obj_magic_test.cmj test/obj_type_test.cmi test/obj_type_test.cmj test/ocaml_re_test.cmi test/ocaml_re_test.cmj test/of_string_test.cmi test/of_string_test.cmj test/offset.cmi test/offset.cmj test/oo_js_test_date.cmi test/oo_js_test_date.cmj test/option_encoding_test.cmi test/option_encoding_test.cmj test/option_record_none_test.cmi test/option_record_none_test.cmj test/option_repr_test.cmi test/option_repr_test.cmj test/optional_ffi_test.cmi test/optional_ffi_test.cmj test/optional_regression_test.cmi test/optional_regression_test.cmj test/pipe_send_readline.cmi test/pipe_send_readline.cmj test/pipe_syntax.cmi test/pipe_syntax.cmj test/poly_empty_array.cmi test/poly_empty_array.cmj test/poly_type.cmi test/poly_type.cmj test/poly_variant_test.cmi test/poly_variant_test.cmj test/polymorphic_raw_test.cmi test/polymorphic_raw_test.cmj test/polymorphism_test.cmi test/polymorphism_test.cmj test/polyvar_convert.cmi test/polyvar_convert.cmj test/polyvar_test.cmi test/polyvar_test.cmj test/ppx_apply_test.cmi test/ppx_apply_test.cmj test/ppx_this_obj_field.cmi test/ppx_this_obj_field.cmj test/ppx_this_obj_test.cmi test/ppx_this_obj_test.cmj test/pq_test.cmi test/pq_test.cmj test/pr6726.cmi test/pr6726.cmj test/pr_regression_test.cmi test/pr_regression_test.cmj test/prepend_data_ffi.cmi test/prepend_data_ffi.cmj test/primitive_reg_test.cmi test/primitive_reg_test.cmj test/print_alpha_test.cmi test/print_alpha_test.cmj test/promise.cmi test/promise.cmj test/promise_catch_test.cmi test/promise_catch_test.cmj test/queue_402.cmi test/queue_402.cmj test/queue_test.cmi test/queue_test.cmj test/random_test.cmi test/random_test.cmj test/raw_hash_tbl_bench.cmi test/raw_hash_tbl_bench.cmj test/raw_output_test.cmi test/raw_output_test.cmj test/raw_pure_test.cmi test/raw_pure_test.cmj test/rbset.cmi test/rbset.cmj test/react.cmi test/react.cmj test/reactDOMRe.cmi test/reactDOMRe.cmj test/reactDOMServerRe.cmi test/reactDOMServerRe.cmj test/reactEvent.cmi test/reactEvent.cmj test/reactTestUtils.cmi test/reactTestUtils.cmj test/reasonReact.cmi test/reasonReact.cmj test/reasonReactCompat.cmi test/reasonReactCompat.cmj test/reasonReactOptimizedCreateClass.cmi test/reasonReactOptimizedCreateClass.cmj test/reasonReactRouter.cmi test/reasonReactRouter.cmj test/rebind_module.cmi test/rebind_module.cmj test/rebind_module_test.cmi test/rebind_module_test.cmj test/rec_array_test.cmi test/rec_array_test.cmj test/rec_fun_test.cmi test/rec_fun_test.cmj test/rec_module_opt.cmi test/rec_module_opt.cmj test/rec_module_test.cmi test/rec_module_test.cmj test/rec_value_test.cmi test/rec_value_test.cmj test/record_debug_test.cmi test/record_debug_test.cmj test/record_extension_test.cmi test/record_extension_test.cmj test/record_name_test.cmi test/record_name_test.cmj test/record_regression.cmi test/record_regression.cmj test/record_with_test.cmi test/record_with_test.cmj test/recursive_module.cmi test/recursive_module.cmj test/recursive_module_test.cmi test/recursive_module_test.cmj test/recursive_react_component.cmi test/recursive_react_component.cmj test/recursive_records_test.cmi test/recursive_records_test.cmj test/recursive_unbound_module_test.cmi test/recursive_unbound_module_test.cmj test/regression_print.cmi test/regression_print.cmj test/relative_path.cmi test/relative_path.cmj test/res_debug.cmi test/res_debug.cmj test/return_check.cmi test/return_check.cmj test/runtime_encoding_test.cmi test/runtime_encoding_test.cmj test/set_gen.cmi test/set_gen.cmj test/sexp.cmi test/sexp.cmj test/sexpm.cmi test/sexpm.cmj test/sexpm_test.cmi test/sexpm_test.cmj test/side_effect.cmi test/side_effect.cmj test/side_effect_free.cmi test/side_effect_free.cmj test/simple_derive_test.cmi test/simple_derive_test.cmj test/simple_derive_use.cmi test/simple_derive_use.cmj test/simple_lexer_test.cmi test/simple_lexer_test.cmj test/simplify_lambda_632o.cmi test/simplify_lambda_632o.cmj test/single_module_alias.cmi test/single_module_alias.cmj test/singular_unit_test.cmi test/singular_unit_test.cmj test/small_inline_test.cmi test/small_inline_test.cmj test/splice_test.cmi test/splice_test.cmj test/stack_comp_test.cmi test/stack_comp_test.cmj test/stack_test.cmi test/stack_test.cmj test/stream_parser_test.cmi test/stream_parser_test.cmj test/string_bound_get_test.cmi test/string_bound_get_test.cmj test/string_get_set_test.cmi test/string_get_set_test.cmj test/string_interp_test.cmi test/string_interp_test.cmj test/string_literal_print_test.cmi test/string_literal_print_test.cmj test/string_runtime_test.cmi test/string_runtime_test.cmj test/string_set.cmi test/string_set.cmj test/string_set_test.cmi test/string_set_test.cmj test/string_test.cmi test/string_test.cmj test/string_unicode_test.cmi test/string_unicode_test.cmj test/stringmatch_test.cmi test/stringmatch_test.cmj test/submodule.cmi test/submodule.cmj test/submodule_call.cmi test/submodule_call.cmj test/switch_case_test.cmi test/switch_case_test.cmj test/tailcall_inline_test.cmi test/tailcall_inline_test.cmj test/template.cmi test/template.cmj test/test.cmi test/test.cmj test/test2.cmi test/test2.cmj test/test_alias.cmi test/test_alias.cmj test/test_ari.cmi test/test_ari.cmj test/test_array.cmi test/test_array.cmj test/test_array_append.cmi test/test_array_append.cmj test/test_array_primitive.cmi test/test_array_primitive.cmj test/test_bool_equal.cmi test/test_bool_equal.cmj test/test_bs_this.cmi test/test_bs_this.cmj test/test_bug.cmi test/test_bug.cmj test/test_bytes.cmi test/test_bytes.cmj test/test_case_opt_collision.cmi test/test_case_opt_collision.cmj test/test_case_set.cmi test/test_case_set.cmj test/test_char.cmi test/test_char.cmj test/test_closure.cmi test/test_closure.cmj test/test_common.cmi test/test_common.cmj test/test_const_elim.cmi test/test_const_elim.cmj test/test_const_propogate.cmi test/test_const_propogate.cmj test/test_cpp.cmi test/test_cpp.cmj test/test_cps.cmi test/test_cps.cmj test/test_demo.cmi test/test_demo.cmj test/test_dup_param.cmi test/test_dup_param.cmj test/test_eq.cmi test/test_eq.cmj test/test_exception.cmi test/test_exception.cmj test/test_exception_escape.cmi test/test_exception_escape.cmj test/test_export2.cmi test/test_export2.cmj test/test_external.cmi test/test_external.cmj test/test_external_unit.cmi test/test_external_unit.cmj test/test_ffi.cmi test/test_ffi.cmj test/test_fib.cmi test/test_fib.cmj test/test_filename.cmi test/test_filename.cmj test/test_for_loop.cmi test/test_for_loop.cmj test/test_for_map.cmi test/test_for_map.cmj test/test_for_map2.cmi test/test_for_map2.cmj test/test_format.cmi test/test_format.cmj test/test_formatter.cmi test/test_formatter.cmj test/test_functor_dead_code.cmi test/test_functor_dead_code.cmj test/test_generative_module.cmi test/test_generative_module.cmj test/test_global_print.cmi test/test_global_print.cmj test/test_google_closure.cmi test/test_google_closure.cmj test/test_http_server.cmi test/test_http_server.cmj test/test_include.cmi test/test_include.cmj test/test_incomplete.cmi test/test_incomplete.cmj test/test_incr_ref.cmi test/test_incr_ref.cmj test/test_index.cmi test/test_index.cmj test/test_int_map_find.cmi test/test_int_map_find.cmj test/test_internalOO.cmi test/test_internalOO.cmj test/test_is_js.cmi test/test_is_js.cmj test/test_js_ffi.cmi test/test_js_ffi.cmj test/test_let.cmi test/test_let.cmj test/test_list.cmi test/test_list.cmj test/test_literal.cmi test/test_literal.cmj test/test_literals.cmi test/test_literals.cmj test/test_match_exception.cmi test/test_match_exception.cmj test/test_mutliple.cmi test/test_mutliple.cmj test/test_nat64.cmi test/test_nat64.cmj test/test_nested_let.cmi test/test_nested_let.cmj test/test_nested_print.cmi test/test_nested_print.cmj test/test_non_export.cmi test/test_non_export.cmj test/test_nullary.cmi test/test_nullary.cmj test/test_obj.cmi test/test_obj.cmj test/test_obj_simple_ffi.cmi test/test_obj_simple_ffi.cmj test/test_order.cmi test/test_order.cmj test/test_order_tailcall.cmi test/test_order_tailcall.cmj test/test_other_exn.cmi test/test_other_exn.cmj test/test_pack.cmi test/test_pack.cmj test/test_per.cmi test/test_per.cmj test/test_pervasive.cmi test/test_pervasive.cmj test/test_pervasives2.cmi test/test_pervasives2.cmj test/test_pervasives3.cmi test/test_pervasives3.cmj test/test_primitive.cmi test/test_primitive.cmj test/test_promise_bind.cmi test/test_promise_bind.cmj test/test_ramification.cmi test/test_ramification.cmj test/test_react.cmi test/test_react.cmj test/test_react_case.cmi test/test_react_case.cmj test/test_regex.cmi test/test_regex.cmj test/test_require.cmi test/test_require.cmj test/test_runtime_encoding.cmi test/test_runtime_encoding.cmj test/test_scope.cmi test/test_scope.cmj test/test_seq.cmi test/test_seq.cmj test/test_set.cmi test/test_set.cmj test/test_side_effect_functor.cmi test/test_side_effect_functor.cmj test/test_simple_include.cmi test/test_simple_include.cmj test/test_simple_pattern_match.cmi test/test_simple_pattern_match.cmj test/test_simple_ref.cmi test/test_simple_ref.cmj test/test_simple_tailcall.cmi test/test_simple_tailcall.cmj test/test_small.cmi test/test_small.cmj test/test_sprintf.cmi test/test_sprintf.cmj test/test_stack.cmi test/test_stack.cmj test/test_static_catch_ident.cmi test/test_static_catch_ident.cmj test/test_string.cmi test/test_string.cmj test/test_string_case.cmi test/test_string_case.cmj test/test_string_const.cmi test/test_string_const.cmj test/test_string_map.cmi test/test_string_map.cmj test/test_string_switch.cmi test/test_string_switch.cmj test/test_switch.cmi test/test_switch.cmj test/test_trywith.cmi test/test_trywith.cmj test/test_tuple.cmi test/test_tuple.cmj test/test_tuple_destructring.cmi test/test_tuple_destructring.cmj test/test_type_based_arity.cmi test/test_type_based_arity.cmj test/test_u.cmi test/test_u.cmj test/test_unknown.cmi test/test_unknown.cmj test/test_unsafe_cmp.cmi test/test_unsafe_cmp.cmj test/test_unsafe_obj_ffi.cmi test/test_unsafe_obj_ffi.cmj test/test_unsafe_obj_ffi_ppx.cmi test/test_unsafe_obj_ffi_ppx.cmj test/test_unsupported_primitive.cmi test/test_unsupported_primitive.cmj test/test_while_closure.cmi test/test_while_closure.cmj test/test_while_side_effect.cmi test/test_while_side_effect.cmj test/test_zero_nullable.cmi test/test_zero_nullable.cmj test/then_mangle_test.cmi test/then_mangle_test.cmj test/ticker.cmi test/ticker.cmj test/to_string_test.cmi test/to_string_test.cmj test/topsort_test.cmi test/topsort_test.cmj test/tramp_fib.cmi test/tramp_fib.cmj test/tuple_alloc.cmi test/tuple_alloc.cmj test/type_disambiguate.cmi test/type_disambiguate.cmj test/typeof_test.cmi test/typeof_test.cmj test/ui_defs.cmi test/unboxed_attribute.cmi test/unboxed_attribute.cmj test/unboxed_attribute_test.cmi test/unboxed_attribute_test.cmj test/unboxed_crash.cmi test/unboxed_crash.cmj test/unboxed_use_case.cmi test/unboxed_use_case.cmj test/uncurried_cast.cmi test/uncurried_cast.cmj test/uncurried_default.args.cmi test/uncurried_default.args.cmj test/uncurried_pipe.cmi test/uncurried_pipe.cmj test/uncurry_external_test.cmi test/uncurry_external_test.cmj test/uncurry_glob_test.cmi test/uncurry_glob_test.cmj test/uncurry_method.cmi test/uncurry_method.cmj test/uncurry_test.cmi test/uncurry_test.cmj test/undef_regression2_test.cmi test/undef_regression2_test.cmj test/undef_regression_test.cmi test/undef_regression_test.cmj test/undefine_conditional.cmi test/undefine_conditional.cmj test/unicode_type_error.cmi test/unicode_type_error.cmj test/unit_undefined_test.cmi test/unit_undefined_test.cmj test/unitest_string.cmi test/unitest_string.cmj test/unsafe_full_apply_primitive.cmi test/unsafe_full_apply_primitive.cmj test/unsafe_obj_external.cmi test/unsafe_obj_external.cmj test/unsafe_ppx_test.cmi test/unsafe_ppx_test.cmj test/unsafe_this.cmi test/unsafe_this.cmj test/update_record_test.cmi test/update_record_test.cmj test/utf8_decode_test.cmi test/utf8_decode_test.cmj test/variant.cmi test/variant.cmj test/watch_test.cmi test/watch_test.cmj test/webpack_config.cmi test/webpack_config.cmj diff --git a/jscomp/test/uncurried_default.args.js b/jscomp/test/uncurried_default.args.js new file mode 100644 index 0000000000..7aacac8315 --- /dev/null +++ b/jscomp/test/uncurried_default.args.js @@ -0,0 +1,53 @@ +'use strict'; + +var Curry = require("../../lib/js/curry.js"); + +function withOpt(xOpt, y) { + var x = xOpt !== undefined ? xOpt : 1; + return function (zOpt, w) { + var z = zOpt !== undefined ? zOpt : 1; + return ((x + y | 0) + z | 0) + w | 0; + }; +} + +var testWithOpt = withOpt(undefined, 3)(undefined, 4); + +var partial_arg = 10; + +var partial = Curry._1((function (param) { + return withOpt(partial_arg, param); + })(3), 4)(11); + +var total = withOpt(10, 3)(4, 11); + +var StandardNotation = { + withOpt: withOpt, + testWithOpt: testWithOpt, + partial: partial, + total: total +}; + +function withOpt$1(xOpt, y) { + var x = xOpt !== undefined ? xOpt : 1; + return function (zOpt, w) { + var z = zOpt !== undefined ? zOpt : 1; + return ((x + y | 0) + z | 0) + w | 0; + }; +} + +var testWithOpt$1 = withOpt$1(undefined, 3)(undefined, 4); + +var partial_arg$1 = 10; + +var partial$1 = Curry._1((function (param) { + return withOpt$1(partial_arg$1, param); + })(3), 4)(11); + +var total$1 = withOpt$1(10, 3)(4, 11); + +exports.StandardNotation = StandardNotation; +exports.withOpt = withOpt$1; +exports.testWithOpt = testWithOpt$1; +exports.partial = partial$1; +exports.total = total$1; +/* testWithOpt Not a pure module */ diff --git a/jscomp/test/uncurried_default.args.res b/jscomp/test/uncurried_default.args.res new file mode 100644 index 0000000000..346f4458bc --- /dev/null +++ b/jscomp/test/uncurried_default.args.res @@ -0,0 +1,15 @@ +module StandardNotation = { + let withOpt = (. ~x=1, y) => (. ~z=1, w) => x+y+z+w + let testWithOpt = withOpt(. 3)(. 4) + let partial = withOpt(~x=10)(3)(~z=4)(11) + let total = withOpt(. ~x=10, 3)(. ~z=4, 11) +} + +@@uncurried + +open StandardNotation + +let withOpt = (~x=1, y) => (~z=1, w) => x+y+z+w +let testWithOpt = withOpt(3)(4) +let partial = withOpt(. ~x=10)(. 3)(. ~z=4)(. 11) +let total = withOpt(~x=10, 3)(~z=4, 11) From 9b04e92c990cba7af0e07107aa8ada7176614cc3 Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 23 Nov 2022 11:55:19 +0100 Subject: [PATCH 5/6] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc11141d2..40ad4ae469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ subset of the arguments, and return a curried type with the remaining ones https://github.com/rescript-lang/rescript-compiler/pull/5805 - Add support for uncurried externals https://github.com/rescript-lang/rescript-compiler/pull/5815 https://github.com/rescript-lang/rescript-compiler/pull/5819 https://github.com/rescript-lang/rescript-compiler/pull/5830 - Parser/Printer: unify uncurried functions of arity 0, and of arity 1 taking unit. There's now only arity 1 in the source language. https://github.com/rescript-lang/rescript-compiler/pull/5825 +- Add support for default arguments in uncurried functions https://github.com/rescript-lang/rescript-compiler/pull/5835 #### :boom: Breaking Change From 6329aa583f89a21a622ebb66ba469af3e9c73cbf Mon Sep 17 00:00:00 2001 From: Cristiano Calcagno Date: Wed, 23 Nov 2022 13:55:12 +0100 Subject: [PATCH 6/6] clean up --- jscomp/frontend/ast_exp_apply.ml | 21 +++++++------------ lib/4.06.1/unstable/js_compiler.ml | 21 +++++++------------ lib/4.06.1/unstable/js_playground_compiler.ml | 21 +++++++------------ lib/4.06.1/whole_compiler.ml | 21 +++++++------------ 4 files changed, 32 insertions(+), 52 deletions(-) diff --git a/jscomp/frontend/ast_exp_apply.ml b/jscomp/frontend/ast_exp_apply.ml index a0d078e553..33268b8377 100644 --- a/jscomp/frontend/ast_exp_apply.ml +++ b/jscomp/frontend/ast_exp_apply.ml @@ -156,19 +156,14 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) pexp_attributes = f.pexp_attributes; pexp_loc = f.pexp_loc; }) - | _ -> ( - match - ( Ext_list.exclude_with_val f_.pexp_attributes - Ast_attributes.is_bs, - f_.pexp_desc ) - with - | _ when op = "|.u" -> - (* a |.u f - Uncurried unary application *) - Ast_compatible.app1 ~loc - ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) - f a - | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) + | _ -> + if op = "|.u" then + (* a |.u f + Uncurried unary application *) + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a + else Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property - obj#(method a b ) diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 716dad3f82..0945fca2c3 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -150581,19 +150581,14 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) pexp_attributes = f.pexp_attributes; pexp_loc = f.pexp_loc; }) - | _ -> ( - match - ( Ext_list.exclude_with_val f_.pexp_attributes - Ast_attributes.is_bs, - f_.pexp_desc ) - with - | _ when op = "|.u" -> - (* a |.u f - Uncurried unary application *) - Ast_compatible.app1 ~loc - ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) - f a - | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) + | _ -> + if op = "|.u" then + (* a |.u f + Uncurried unary application *) + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a + else Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property - obj#(method a b ) diff --git a/lib/4.06.1/unstable/js_playground_compiler.ml b/lib/4.06.1/unstable/js_playground_compiler.ml index 8c9d6cc1c5..3591fd1e9a 100644 --- a/lib/4.06.1/unstable/js_playground_compiler.ml +++ b/lib/4.06.1/unstable/js_playground_compiler.ml @@ -150581,19 +150581,14 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) pexp_attributes = f.pexp_attributes; pexp_loc = f.pexp_loc; }) - | _ -> ( - match - ( Ext_list.exclude_with_val f_.pexp_attributes - Ast_attributes.is_bs, - f_.pexp_desc ) - with - | _ when op = "|.u" -> - (* a |.u f - Uncurried unary application *) - Ast_compatible.app1 ~loc - ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) - f a - | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) + | _ -> + if op = "|.u" then + (* a |.u f + Uncurried unary application *) + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a + else Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property - obj#(method a b ) diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index b09f4bf26e..44a33a30f0 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -160865,19 +160865,14 @@ let app_exp_mapper (e : exp) (self : Bs_ast_mapper.mapper) (fn : exp) pexp_attributes = f.pexp_attributes; pexp_loc = f.pexp_loc; }) - | _ -> ( - match - ( Ext_list.exclude_with_val f_.pexp_attributes - Ast_attributes.is_bs, - f_.pexp_desc ) - with - | _ when op = "|.u" -> - (* a |.u f - Uncurried unary application *) - Ast_compatible.app1 ~loc - ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) - f a - | _ -> Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a)) + | _ -> + if op = "|.u" then + (* a |.u f + Uncurried unary application *) + Ast_compatible.app1 ~loc + ~attrs:(Ast_attributes.res_uapp :: e.pexp_attributes) + f a + else Ast_compatible.app1 ~loc ~attrs:e.pexp_attributes f a) | Some { op = "##"; loc; args = [ obj; rest ] } -> ( (* - obj##property - obj#(method a b )