From 124c091611b82e4a5901af7834ccb148b50142f8 Mon Sep 17 00:00:00 2001 From: Cheng Lou Date: Wed, 10 Feb 2021 03:16:49 -0800 Subject: [PATCH 1/2] [Super errors] better arity mismatch error for uncurried function Fixes #4939 The previous message was also wrong (?). The types were flipped; if the function expected 1 and got 2, it'd say "this function has arity2 but was expected arity1". --- .../expected/arity_mismatch.re.expected | 2 +- .../expected/arity_mismatch2.re.expected | 2 +- jscomp/super_errors/super_typecore.ml | 24 +++++++++++++++---- lib/4.06.1/unstable/js_compiler.ml | 24 +++++++++++++++---- lib/4.06.1/whole_compiler.ml | 24 +++++++++++++++---- 5 files changed, 62 insertions(+), 14 deletions(-) diff --git a/jscomp/build_tests/super_errors/expected/arity_mismatch.re.expected b/jscomp/build_tests/super_errors/expected/arity_mismatch.re.expected index 5847e239f4..46674aaecf 100644 --- a/jscomp/build_tests/super_errors/expected/arity_mismatch.re.expected +++ b/jscomp/build_tests/super_errors/expected/arity_mismatch.re.expected @@ -6,4 +6,4 @@ 2 │ let makeVar = (. ~f, ()) => 34; 3 │ let makeVariables = makeVar(. ~f=f => f); - This function has arity2 but was expected arity1 \ No newline at end of file + This function expected 2 arguments, but got 1 \ No newline at end of file diff --git a/jscomp/build_tests/super_errors/expected/arity_mismatch2.re.expected b/jscomp/build_tests/super_errors/expected/arity_mismatch2.re.expected index b57d8f88b5..9a99a99c0a 100644 --- a/jscomp/build_tests/super_errors/expected/arity_mismatch2.re.expected +++ b/jscomp/build_tests/super_errors/expected/arity_mismatch2.re.expected @@ -6,4 +6,4 @@ 2 │ let makeVar = (. f, ()) => 34; 3 │ let makeVariables = makeVar(. 1,2,3); - This function has arity2 but was expected arity3 \ No newline at end of file + This function expected 2 arguments, but got 3 \ No newline at end of file diff --git a/jscomp/super_errors/super_typecore.ml b/jscomp/super_errors/super_typecore.ml index 4808c5be1d..25dd6d9796 100644 --- a/jscomp/super_errors/super_typecore.ml +++ b/jscomp/super_errors/super_typecore.ml @@ -124,6 +124,22 @@ let print_expr_type_clash env trace ppf = begin show_extra_help ppf env trace; end +let reportJsFnArityMismatch ~arityA ~arityB ppf = + let extractArity s = + if Ext_string.starts_with s "arity" then + (* get the number part of e.g. arity12 *) + (* assumption: the module Js.Fn only contains types from arity0 to arity22 *) + String.sub s 5 ((String.length s) - 5) + else + raise (Invalid_argument "Unrecognized arity type name.") + in + let firstNumber = extractArity arityA in + fprintf ppf "This function expected @{%s@} %s, but got @{%s@}" + firstNumber + (if firstNumber = "1" then "argument" else "arguments") + (extractArity arityB) + + (* Pasted from typecore.ml. Needed for some cases in report_error below *) (* Records *) let label_of_kind kind = @@ -169,10 +185,10 @@ let report_error env ppf = function ) -> fprintf ppf "This function is a curried function where an uncurried function is expected" | Expr_type_clash ( - (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),_,_)}) :: - (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),b,_),_,_)}) :: _ - ) when a <> b -> - fprintf ppf "This function has %s but was expected %s" a b + (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),arityA,_),_,_)}) :: + (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),arityB,_),_,_)}) :: _ + ) -> + reportJsFnArityMismatch ~arityA ~arityB ppf | Expr_type_clash ( (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js_OO"},"Meth",_),a,_),_,_)}) :: (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js_OO"},"Meth",_),b,_),_,_)}) :: _ diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index eccc693367..42ef2611a9 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -409843,6 +409843,22 @@ let print_expr_type_clash env trace ppf = begin show_extra_help ppf env trace; end +let reportJsFnArityMismatch ~arityA ~arityB ppf = + let extractArity s = + if Ext_string.starts_with s "arity" then + (* get the number part of e.g. arity12 *) + (* assumption: the module Js.Fn only contains types from arity0 to arity22 *) + String.sub s 5 ((String.length s) - 5) + else + raise (Invalid_argument "Unrecognized arity type name.") + in + let firstNumber = extractArity arityA in + fprintf ppf "This function expected @{%s@} %s, but got @{%s@}" + firstNumber + (if firstNumber = "1" then "argument" else "arguments") + (extractArity arityB) + + (* Pasted from typecore.ml. Needed for some cases in report_error below *) (* Records *) let label_of_kind kind = @@ -409888,10 +409904,10 @@ let report_error env ppf = function ) -> fprintf ppf "This function is a curried function where an uncurried function is expected" | Expr_type_clash ( - (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),_,_)}) :: - (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),b,_),_,_)}) :: _ - ) when a <> b -> - fprintf ppf "This function has %s but was expected %s" a b + (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),arityA,_),_,_)}) :: + (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),arityB,_),_,_)}) :: _ + ) -> + reportJsFnArityMismatch ~arityA ~arityB ppf | Expr_type_clash ( (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js_OO"},"Meth",_),a,_),_,_)}) :: (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js_OO"},"Meth",_),b,_),_,_)}) :: _ diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index ff1e35fa17..65ace41b3c 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -435726,6 +435726,22 @@ let print_expr_type_clash env trace ppf = begin show_extra_help ppf env trace; end +let reportJsFnArityMismatch ~arityA ~arityB ppf = + let extractArity s = + if Ext_string.starts_with s "arity" then + (* get the number part of e.g. arity12 *) + (* assumption: the module Js.Fn only contains types from arity0 to arity22 *) + String.sub s 5 ((String.length s) - 5) + else + raise (Invalid_argument "Unrecognized arity type name.") + in + let firstNumber = extractArity arityA in + fprintf ppf "This function expected @{%s@} %s, but got @{%s@}" + firstNumber + (if firstNumber = "1" then "argument" else "arguments") + (extractArity arityB) + + (* Pasted from typecore.ml. Needed for some cases in report_error below *) (* Records *) let label_of_kind kind = @@ -435771,10 +435787,10 @@ let report_error env ppf = function ) -> fprintf ppf "This function is a curried function where an uncurried function is expected" | Expr_type_clash ( - (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),a,_),_,_)}) :: - (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),b,_),_,_)}) :: _ - ) when a <> b -> - fprintf ppf "This function has %s but was expected %s" a b + (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),arityA,_),_,_)}) :: + (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js"},"Fn",_),arityB,_),_,_)}) :: _ + ) -> + reportJsFnArityMismatch ~arityA ~arityB ppf | Expr_type_clash ( (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js_OO"},"Meth",_),a,_),_,_)}) :: (_, {desc = Tconstr (Pdot (Pdot(Pident {name = "Js_OO"},"Meth",_),b,_),_,_)}) :: _ From 451f5576f0d71faa29680f35dde8bf0ef802c31c Mon Sep 17 00:00:00 2001 From: Cheng Lou Date: Wed, 10 Feb 2021 03:16:49 -0800 Subject: [PATCH 2/2] [Super errors] Fixes another uncurried arity mismatch report --- .../expected/arity_mismatch3.re.expected | 3 +-- jscomp/super_errors/super_typecore.ml | 14 ++++++++++++++ lib/4.06.1/unstable/js_compiler.ml | 14 ++++++++++++++ lib/4.06.1/whole_compiler.ml | 14 ++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/jscomp/build_tests/super_errors/expected/arity_mismatch3.re.expected b/jscomp/build_tests/super_errors/expected/arity_mismatch3.re.expected index f99b70f150..12d0ec2bb3 100644 --- a/jscomp/build_tests/super_errors/expected/arity_mismatch3.re.expected +++ b/jscomp/build_tests/super_errors/expected/arity_mismatch3.re.expected @@ -4,5 +4,4 @@ 1 │ Belt.Array.mapU([||], (. a, b) => 1); - The field Js.Fn.I2 belongs to the record type Js.Fn.arity2 - but a field was expected belonging to the record type Js.Fn.arity1 \ No newline at end of file + This function expected 1 argument, but got 2 \ No newline at end of file diff --git a/jscomp/super_errors/super_typecore.ml b/jscomp/super_errors/super_typecore.ml index 25dd6d9796..78c2607ebe 100644 --- a/jscomp/super_errors/super_typecore.ml +++ b/jscomp/super_errors/super_typecore.ml @@ -292,6 +292,20 @@ let report_error env ppf = function name (*kind*) Printtyp.path p; end; spellcheck ppf name valid_names; + | Name_type_mismatch ( + "record", + Ldot (Ldot ((Lident "Js"), "Fn"), _arityFieldName), + ( + _, + (Pdot (Pdot ((Pident {name = "Js"}), "Fn", _), arityA, _)) + ), + [( + _, + (Pdot (Pdot ((Pident {name = "Js"}), "Fn", _), arityB, _)) + )] + ) -> + (* modified *) + reportJsFnArityMismatch ~arityA ~arityB ppf | anythingElse -> Typecore.super_report_error_no_wrap_printing_env env ppf anythingElse diff --git a/lib/4.06.1/unstable/js_compiler.ml b/lib/4.06.1/unstable/js_compiler.ml index 42ef2611a9..a31ec313b5 100644 --- a/lib/4.06.1/unstable/js_compiler.ml +++ b/lib/4.06.1/unstable/js_compiler.ml @@ -410011,6 +410011,20 @@ let report_error env ppf = function name (*kind*) Printtyp.path p; end; spellcheck ppf name valid_names; + | Name_type_mismatch ( + "record", + Ldot (Ldot ((Lident "Js"), "Fn"), _arityFieldName), + ( + _, + (Pdot (Pdot ((Pident {name = "Js"}), "Fn", _), arityA, _)) + ), + [( + _, + (Pdot (Pdot ((Pident {name = "Js"}), "Fn", _), arityB, _)) + )] + ) -> + (* modified *) + reportJsFnArityMismatch ~arityA ~arityB ppf | anythingElse -> Typecore.super_report_error_no_wrap_printing_env env ppf anythingElse diff --git a/lib/4.06.1/whole_compiler.ml b/lib/4.06.1/whole_compiler.ml index 65ace41b3c..40b12abf34 100644 --- a/lib/4.06.1/whole_compiler.ml +++ b/lib/4.06.1/whole_compiler.ml @@ -435894,6 +435894,20 @@ let report_error env ppf = function name (*kind*) Printtyp.path p; end; spellcheck ppf name valid_names; + | Name_type_mismatch ( + "record", + Ldot (Ldot ((Lident "Js"), "Fn"), _arityFieldName), + ( + _, + (Pdot (Pdot ((Pident {name = "Js"}), "Fn", _), arityA, _)) + ), + [( + _, + (Pdot (Pdot ((Pident {name = "Js"}), "Fn", _), arityB, _)) + )] + ) -> + (* modified *) + reportJsFnArityMismatch ~arityA ~arityB ppf | anythingElse -> Typecore.super_report_error_no_wrap_printing_env env ppf anythingElse