]> granicus.if.org Git - vim/commitdiff
patch 8.2.3100: Vim9: no error when using type with unknown number of args v8.2.3100
authorBram Moolenaar <Bram@vim.org>
Sun, 4 Jul 2021 13:54:08 +0000 (15:54 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 4 Jul 2021 13:54:08 +0000 (15:54 +0200)
Problem:    Vim9: no error when using type with unknown number of arguments.
Solution:   Do not ignore argument count of -1. (closes #8492)

src/evalfunc.c
src/proto/evalfunc.pro
src/testdir/test_vim9_assign.vim
src/testdir/test_vim9_expr.vim
src/testdir/test_vim9_func.vim
src/version.c
src/vim9type.c

index e635116786e9bfbbbb5a8382b15f505fc18aa45f..ec74fdeeae9d270332e63ff5c9c50e328fde715b 100644 (file)
@@ -2054,6 +2054,18 @@ internal_func_check_arg_types(
     return OK;
 }
 
+/*
+ * Get the argument count for function "idx".
+ * "argcount" is the total argument count, "min_argcount" the non-optional
+ * argument count.
+ */
+    void
+internal_func_get_argcount(int idx, int *argcount, int *min_argcount)
+{
+    *argcount = global_functions[idx].f_max_argc;
+    *min_argcount = global_functions[idx].f_min_argc;
+}
+
 /*
  * Call the "f_retfunc" function to obtain the return type of function "idx".
  * "argtypes" is the list of argument types or NULL when there are no
index c1ac55f5b9fd3e98b982da5993247a0fa992b291..3faff292a720ff79b30a73e535d179b864594591 100644 (file)
@@ -6,6 +6,7 @@ int find_internal_func(char_u *name);
 int has_internal_func(char_u *name);
 char *internal_func_name(int idx);
 int internal_func_check_arg_types(type_T **types, int idx, int argcount, cctx_T *cctx);
+void internal_func_get_argcount(int idx, int *argcount, int *min_argcount);
 type_T *internal_func_ret_type(int idx, int argcount, type_T **argtypes);
 int internal_func_is_map(int idx);
 int check_internal_func(int idx, int argcount);
@@ -21,7 +22,6 @@ void f_has(typval_T *argvars, typval_T *rettv);
 int dynamic_feature(char_u *feature);
 void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
 void range_list_materialize(list_T *list);
-float_T vim_round(float_T f);
 long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit);
 void f_string(typval_T *argvars, typval_T *rettv);
 /* vim: set ft=c : */
index 86f890ea09012ed0b77969332983694313aea740..92ffa0055c2b55c7e6967fce9847b5c25c0b2b96 100644 (file)
@@ -650,6 +650,15 @@ def Test_assignment_list()
     d.dd[0] = 0
   END
   CheckDefExecFailure(lines, 'E1147:', 2)
+
+  lines =<< trim END
+      def OneArg(x: bool)
+      enddef
+      def TwoArgs(x: bool, y: bool)
+      enddef
+      var fl: list<func(bool, bool, bool)> = [OneArg, TwoArgs]
+  END
+  CheckDefExecAndScriptFailure(lines, 'E1012:', 5)
 enddef
 
 def Test_assignment_list_any_index()
index 22c68f4ae472d08bb73ae0dfc0e3284e07d02f4d..1e99e9568d48cb949cd456c6e28b0aaae5872606 100644 (file)
@@ -57,7 +57,7 @@ def Test_expr1_trinary()
       assert_equal(function('len'), Res)
 
       var RetOne: func(string): number = function('len')
-      var RetTwo: func(string): number = function('winnr')
+      var RetTwo: func(string): number = function('charcol')
       var RetThat: func = g:atrue ? RetOne : RetTwo
       assert_equal(function('len'), RetThat)
 
index f4142ee851683424536f38a4c44f273b2b53689f..89cdee7437be3aa7bcdf01233bee086e2244ea08 100644 (file)
@@ -1030,7 +1030,7 @@ def Test_pass_legacy_lambda_to_def_func()
 
   lines =<< trim END
       vim9script
-      def g:TestFunc(f: func())
+      def g:TestFunc(f: func)
       enddef
       legacy call g:TestFunc({-> 0})
       delfunc g:TestFunc
index 062e856e04a31978b8e65c2492328d851cbf291c..298fd8799607b069e65268bef681ee0fe2f7a61a 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3100,
 /**/
     3099,
 /**/
index 91dc3fe6077aa11c541e452bd6eed866f141c796..c92e063bb131df3f40015dcac3d64402a469bf1a 100644 (file)
@@ -260,6 +260,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
     type_T  *type;
     type_T  *member_type = &t_any;
     int            argcount = 0;
+    int            min_argcount = 0;
 
     if (tv->v_type == VAR_NUMBER)
        return &t_number;
@@ -337,8 +338,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
 
            if (idx >= 0)
            {
-               // TODO: get actual arg count and types
-               argcount = -1;
+               internal_func_get_argcount(idx, &argcount, &min_argcount);
                member_type = internal_func_ret_type(idx, 0, NULL);
            }
            else
@@ -364,6 +364,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member)
        return NULL;
     type->tt_type = tv->v_type;
     type->tt_argcount = argcount;
+    type->tt_min_argcount = min_argcount;
     type->tt_member = member_type;
 
     return type;
@@ -525,9 +526,9 @@ check_type(type_T *expected, type_T *actual, int give_msg, where_T where)
                ret = check_type(expected->tt_member, actual->tt_member,
                                                                 FALSE, where);
            if (ret == OK && expected->tt_argcount != -1
-                   && actual->tt_argcount != -1
-                   && (actual->tt_argcount < expected->tt_min_argcount
-                       || actual->tt_argcount > expected->tt_argcount))
+                   && (actual->tt_argcount == -1
+                       || (actual->tt_argcount < expected->tt_min_argcount
+                           || actual->tt_argcount > expected->tt_argcount)))
                ret = FAIL;
            if (ret == OK && expected->tt_args != NULL
                                                    && actual->tt_args != NULL)
@@ -1032,7 +1033,10 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
                }
            }
            else
+               // Use -1 for "tt_argcount" to indicate an unknown number of
+               // arguments.
                *dest = alloc_func_type(common, -1, type_gap);
+
            // Use the minimum of min_argcount.
            (*dest)->tt_min_argcount =
                        type1->tt_min_argcount < type2->tt_min_argcount