]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.0703: failing check for argument type for const any v9.0.0703
authorBram Moolenaar <Bram@vim.org>
Sun, 9 Oct 2022 11:55:33 +0000 (12:55 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 9 Oct 2022 11:55:33 +0000 (12:55 +0100)
Problem:    Failing check for argument type for const any.
Solution:   Check for any type properly. (closes #11316)

src/evalfunc.c
src/proto/vim9type.pro
src/testdir/test_vim9_script.vim
src/version.c
src/vim9type.c

index 590b33cbb8b8396689bb5fe3c2176a954d3a3943..a2a5296ae7fd27e8febe1e09cfe43f7c848efcd7 100644 (file)
@@ -257,10 +257,9 @@ arg_type_modifiable(type_T *type, int arg_idx)
     static int
 arg_float_or_nr(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_FLOAT
-           || type->tt_type == VAR_NUMBER)
+    if (type->tt_type == VAR_FLOAT
+           || type->tt_type == VAR_NUMBER
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_number, type, context->arg_idx + 1);
     return FAIL;
@@ -356,10 +355,9 @@ arg_bool(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_LIST
-           || type->tt_type == VAR_BLOB)
+    if (type->tt_type == VAR_LIST
+           || type->tt_type == VAR_BLOB
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
     return FAIL;
@@ -385,10 +383,9 @@ arg_list_or_blob_mod(
     static int
 arg_string_or_nr(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
-           || type->tt_type == VAR_NUMBER)
+    if (type->tt_type == VAR_STRING
+           || type->tt_type == VAR_NUMBER
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -400,10 +397,9 @@ arg_string_or_nr(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_buffer(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
-           || type->tt_type == VAR_NUMBER)
+    if (type->tt_type == VAR_STRING
+           || type->tt_type == VAR_NUMBER
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -415,11 +411,10 @@ arg_buffer(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_buffer_or_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
+    if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_NUMBER
-           || type->tt_type == VAR_DICT)
+           || type->tt_type == VAR_DICT
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -431,10 +426,9 @@ arg_buffer_or_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *con
     static int
 arg_lnum(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
-           || type->tt_type == VAR_NUMBER)
+    if (type->tt_type == VAR_STRING
+           || type->tt_type == VAR_NUMBER
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -446,9 +440,8 @@ arg_lnum(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_string_or_list_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING)
+    if (type->tt_type == VAR_STRING
+           || type_any_or_unknown(type))
        return OK;
     if (type->tt_type != VAR_LIST)
     {
@@ -469,10 +462,9 @@ arg_string_or_list_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *
     static int
 arg_string_or_list_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
-           || type->tt_type == VAR_LIST)
+    if (type->tt_type == VAR_STRING
+           || type->tt_type == VAR_LIST
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -484,10 +476,9 @@ arg_string_or_list_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *con
     static int
 arg_string_or_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
-           || type->tt_type == VAR_DICT)
+    if (type->tt_type == VAR_STRING
+           || type->tt_type == VAR_DICT
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -499,10 +490,9 @@ arg_string_or_dict_any(type_T *type, type_T *decl_type UNUSED, argcontext_T *con
     static int
 arg_string_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
-           || type->tt_type == VAR_BLOB)
+    if (type->tt_type == VAR_STRING
+           || type->tt_type == VAR_BLOB
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -514,10 +504,9 @@ arg_string_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context
     static int
 arg_list_or_dict(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_LIST
-           || type->tt_type == VAR_DICT)
+    if (type->tt_type == VAR_LIST
+           || type->tt_type == VAR_DICT
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
     return FAIL;
@@ -547,11 +536,10 @@ arg_list_or_dict_or_blob_mod(
        type_T       *decl_type UNUSED,
        argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_LIST
+    if (type->tt_type == VAR_LIST
            || type->tt_type == VAR_DICT
-           || type->tt_type == VAR_BLOB)
+           || type->tt_type == VAR_BLOB
+           || type_any_or_unknown(type))
        return arg_type_modifiable(type, context->arg_idx + 1);
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
     return FAIL;
@@ -563,12 +551,11 @@ arg_list_or_dict_or_blob_mod(
     static int
 arg_list_or_dict_or_blob_or_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_LIST
+    if (type->tt_type == VAR_LIST
            || type->tt_type == VAR_DICT
            || type->tt_type == VAR_BLOB
-           || type->tt_type == VAR_STRING)
+           || type->tt_type == VAR_STRING
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
     return FAIL;
@@ -642,15 +629,13 @@ check_map_filter_arg2(type_T *type, argcontext_T *context, int is_map)
        }
     }
 
-    if ((type->tt_member != &t_any && type->tt_member != &t_unknown)
-           || args[0] != NULL)
+    if (!type_any_or_unknown(type->tt_member) || args[0] != NULL)
     {
        where_T where = WHERE_INIT;
 
        if (is_map)
            t_func_exp.tt_member = expected_member == NULL
-                                   || type->tt_member == &t_any
-                                   || type->tt_member == &t_unknown
+                                       || type_any_or_unknown(type->tt_member)
                                ? &t_any : expected_member;
        else
            t_func_exp.tt_member = &t_bool;
@@ -673,8 +658,7 @@ arg_filter_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
     if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_PARTIAL
-           || type == &t_unknown
-           || type == &t_any)
+           || type_any_or_unknown(type))
        return OK;
 
     if (type->tt_type == VAR_FUNC)
@@ -691,8 +675,7 @@ arg_map_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
     if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_PARTIAL
-           || type == &t_unknown
-           || type == &t_any)
+           || type_any_or_unknown(type))
        return OK;
 
     if (type->tt_type == VAR_FUNC)
@@ -709,8 +692,7 @@ arg_sort_how(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
     if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_PARTIAL
-           || type == &t_unknown
-           || type == &t_any)
+           || type_any_or_unknown(type))
        return OK;
 
     if (type->tt_type == VAR_FUNC)
@@ -722,8 +704,7 @@ arg_sort_how(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
            args[0] = context->arg_types[0].type_curr->tt_member;
        else
            args[0] = &t_unknown;
-       if ((type->tt_member != &t_any && type->tt_member != &t_unknown)
-               || args[0] != &t_unknown)
+       if (!type_any_or_unknown(type->tt_member) || args[0] != &t_unknown)
        {
            where_T where = WHERE_INIT;
 
@@ -748,13 +729,12 @@ arg_sort_how(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_string_or_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
+    if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_PARTIAL
            || type->tt_type == VAR_FUNC
            || type->tt_type == VAR_BOOL
-           || type->tt_type == VAR_NUMBER)
+           || type->tt_type == VAR_NUMBER
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_func_any, type, context->arg_idx + 1);
     return FAIL;
@@ -766,11 +746,10 @@ arg_string_or_func(type_T *type, type_T *decl_type UNUSED, argcontext_T *context
     static int
 arg_string_list_or_blob(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_LIST
+    if (type->tt_type == VAR_LIST
            || type->tt_type == VAR_BLOB
-           || type->tt_type == VAR_STRING)
+           || type->tt_type == VAR_STRING
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
     return FAIL;
@@ -791,10 +770,9 @@ arg_job(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_chan_or_job(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_CHANNEL
-           || type->tt_type == VAR_JOB)
+    if (type->tt_type == VAR_CHANNEL
+           || type->tt_type == VAR_JOB
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_channel, type, context->arg_idx + 1);
     return FAIL;
@@ -854,11 +832,10 @@ arg_item_of_prev(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_str_or_nr_or_list(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
+    if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_NUMBER
-           || type->tt_type == VAR_LIST)
+           || type->tt_type == VAR_LIST
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -870,10 +847,9 @@ arg_str_or_nr_or_list(type_T *type, type_T *decl_type UNUSED, argcontext_T *cont
     static int
 arg_dict_any_or_string(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_DICT
-           || type->tt_type == VAR_STRING)
+    if (type->tt_type == VAR_DICT
+           || type->tt_type == VAR_STRING
+           || type_any_or_unknown(type))
        return OK;
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
@@ -902,13 +878,12 @@ arg_extend3(type_T *type, type_T *decl_type, argcontext_T *context)
     static int
 arg_get1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_BLOB
+    if (type->tt_type == VAR_BLOB
            || type->tt_type == VAR_LIST
            || type->tt_type == VAR_DICT
            || type->tt_type == VAR_FUNC
-           || type->tt_type == VAR_PARTIAL)
+           || type->tt_type == VAR_PARTIAL
+           || type_any_or_unknown(type))
        return OK;
 
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
@@ -922,13 +897,12 @@ arg_get1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_len1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
+    if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_NUMBER
            || type->tt_type == VAR_BLOB
            || type->tt_type == VAR_LIST
-           || type->tt_type == VAR_DICT)
+           || type->tt_type == VAR_DICT
+           || type_any_or_unknown(type))
        return OK;
 
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
@@ -958,12 +932,11 @@ arg_remove2(type_T *type, type_T *decl_type, argcontext_T *context)
     static int
 arg_repeat1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
+    if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_NUMBER
            || type->tt_type == VAR_BLOB
-           || type->tt_type == VAR_LIST)
+           || type->tt_type == VAR_LIST
+           || type_any_or_unknown(type))
        return OK;
 
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
@@ -977,11 +950,10 @@ arg_repeat1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_slice1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_LIST
+    if (type->tt_type == VAR_LIST
            || type->tt_type == VAR_BLOB
-           || type->tt_type == VAR_STRING)
+           || type->tt_type == VAR_STRING
+           || type_any_or_unknown(type))
        return OK;
 
     arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
@@ -995,11 +967,10 @@ arg_slice1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
     static int
 arg_string_or_list_or_dict(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_STRING
+    if (type->tt_type == VAR_STRING
            || type->tt_type == VAR_LIST
-           || type->tt_type == VAR_DICT)
+           || type->tt_type == VAR_DICT
+           || type_any_or_unknown(type))
        return OK;
 
     semsg(_(e_string_list_or_dict_required_for_argument_nr),
@@ -1014,11 +985,10 @@ arg_string_or_list_or_dict(type_T *type, type_T *decl_type UNUSED, argcontext_T
     static int
 arg_cursor1(type_T *type, type_T *decl_type UNUSED, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY
-           || type->tt_type == VAR_UNKNOWN
-           || type->tt_type == VAR_NUMBER
+    if (type->tt_type == VAR_NUMBER
            || type->tt_type == VAR_STRING
-           || type->tt_type == VAR_LIST)
+           || type->tt_type == VAR_LIST
+           || type_any_or_unknown(type))
        return OK;
 
     arg_type_mismatch(&t_number, type, context->arg_idx + 1);
index 68bb8fa8c2d45e5792c9296e9762a28c7761a335..3c860928b12b20589c2d7590bec5e5275ea7608f 100644 (file)
@@ -9,6 +9,7 @@ type_T *get_dict_type(type_T *member_type, garray_T *type_gap);
 type_T *alloc_func_type(type_T *ret_type, int argcount, garray_T *type_gap);
 type_T *get_func_type(type_T *ret_type, int argcount, garray_T *type_gap);
 int func_type_add_arg_types(type_T *functype, int argcount, garray_T *type_gap);
+int type_any_or_unknown(type_T *type);
 int need_convert_to_bool(type_T *type, typval_T *tv);
 type_T *typval2type(typval_T *tv, int copyID, garray_T *type_gap, int flags);
 type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap);
index 8a4fd3b6c5e292e224692f3c64dec87ef7176206..c736905d93b806da0ae095e378428f1406b2ef9f 100644 (file)
@@ -305,6 +305,25 @@ def Test_const()
       assert_equal(v:t_number, type(foo.bar))
   END
   v9.CheckDefAndScriptSuccess(lines)
+
+  # also when used as a builtin function argument
+  lines =<< trim END
+      vim9script
+
+      def SorterFunc(lhs: dict<string>, rhs: dict<string>): number
+        return lhs.name <# rhs.name ? -1 : 1
+      enddef
+
+      def Run(): void
+        var list =  [{name: "3"}, {name: "2"}]
+        const Sorter = get({}, "unknown", SorterFunc)
+        sort(list, Sorter)
+        assert_equal([{name: "2"}, {name: "3"}], list)
+      enddef
+
+      Run()
+  END
+  v9.CheckScriptSuccess(lines)
 enddef
 
 def Test_const_bang()
index 0e31af346e6cbf0d48130004caa7ee556512c638..e08cf49fbad2fd03ccdc143bea2fac80996f5d0b 100644 (file)
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    703,
 /**/
     702,
 /**/
index 771fbf54b96490b12ec8d4fb69a927e20865d8ad..c8f571dfaea31473a17697b7a4ae3b6781adff52 100644 (file)
@@ -336,6 +336,17 @@ func_type_add_arg_types(
     return OK;
 }
 
+/*
+ * Return TRUE if "type" is NULL, any or unknown.
+ * This also works for const (comparing with &t_any and &t_unknown doesn't).
+ */
+    int
+type_any_or_unknown(type_T *type)
+{
+    return type == NULL || type->tt_type == VAR_ANY
+                                              || type->tt_type == VAR_UNKNOWN;
+}
+
 /*
  * Get a type_T for a typval_T.
  * "type_gap" is used to temporarily create types in.