]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.3188: Vim9: argument types are not checked at compile time v8.2.3188
authorYegappan Lakshmanan <yegappan@yahoo.com>
Tue, 20 Jul 2021 15:51:51 +0000 (17:51 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 20 Jul 2021 15:51:51 +0000 (17:51 +0200)
Problem:    Vim9: argument types are not checked at compile time.
Solution:   Add several more type checks, also at runtime. (Yegappan
            Lakshmanan, closes #8587)

34 files changed:
src/blob.c
src/channel.c
src/clientserver.c
src/cmdexpand.c
src/cmdhist.c
src/dict.c
src/diff.c
src/errors.h
src/eval.c
src/evalbuffer.c
src/evalfunc.c
src/evalvars.c
src/evalwindow.c
src/filepath.c
src/globals.h
src/insexpand.c
src/job.c
src/list.c
src/map.c
src/match.c
src/proto/typval.pro
src/quickfix.c
src/search.c
src/sign.c
src/strings.c
src/terminal.c
src/testdir/test_blob.vim
src/testdir/test_gui.vim
src/testdir/test_vim9_builtin.vim
src/testing.c
src/textprop.c
src/time.c
src/typval.c
src/version.c

index 4685dc97c190e615f6a8535296473247a6c731b1..6855935ec9d67c1a90f9b6efe6fec01c4a784225 100644 (file)
@@ -415,9 +415,16 @@ blob_set_range(blob_T *dest, long n1, long n2, typval_T *src)
 blob_remove(typval_T *argvars, typval_T *rettv)
 {
     int                error = FALSE;
-    long       idx = (long)tv_get_number_chk(&argvars[1], &error);
+    long       idx;
     long       end;
 
+    if (in_vim9script()
+           && (check_for_blob_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_opt_number_arg(argvars, 2) == FAIL))
+       return;
+
+    idx = (long)tv_get_number_chk(&argvars[1], &error);
     if (!error)
     {
        blob_T  *b = argvars[0].vval.v_blob;
index c0572d3311a3971b030ed7b388c2ef497293eb08..5f78777a37bd01dbbe0c7b617a8a175b556e67b5 100644 (file)
@@ -4270,6 +4270,11 @@ ch_expr_common(typval_T *argvars, typval_T *rettv, int eval)
     rettv->v_type = VAR_STRING;
     rettv->vval.v_string = NULL;
 
+    if (in_vim9script()
+           && (check_for_chan_or_job_arg(argvars, 0) == FAIL
+               || check_for_opt_dict_arg(argvars, 2) == FAIL))
+       return;
+
     channel = get_channel_arg(&argvars[0], TRUE, FALSE, 0);
     if (channel == NULL)
        return;
@@ -4330,6 +4335,12 @@ ch_raw_common(typval_T *argvars, typval_T *rettv, int eval)
     rettv->v_type = VAR_STRING;
     rettv->vval.v_string = NULL;
 
+    if (in_vim9script()
+           && (check_for_chan_or_job_arg(argvars, 0) == FAIL
+               || check_for_string_or_blob_arg(argvars, 1) == FAIL
+               || check_for_opt_dict_arg(argvars, 2) == FAIL))
+       return;
+
     if (argvars[1].v_type == VAR_BLOB)
     {
        text = argvars[1].vval.v_blob->bv_ga.ga_data;
@@ -4815,9 +4826,16 @@ f_ch_close_in(typval_T *argvars, typval_T *rettv UNUSED)
     void
 f_ch_getbufnr(typval_T *argvars, typval_T *rettv)
 {
-    channel_T *channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0);
+    channel_T *channel;
 
     rettv->vval.v_number = -1;
+
+    if (in_vim9script()
+           && (check_for_chan_or_job_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL))
+       return;
+
+    channel = get_channel_arg(&argvars[0], FALSE, FALSE, 0);
     if (channel != NULL)
     {
        char_u  *what = tv_get_string(&argvars[1]);
@@ -4894,6 +4912,7 @@ f_ch_logfile(typval_T *argvars, typval_T *rettv UNUSED)
     // Don't open a file in restricted mode.
     if (check_restricted() || check_secure())
        return;
+
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
                || check_for_string_arg(argvars, 1) == FAIL))
index 00bea6f56afb94f31984cb0ce05e978afb474cc2..3c0a930ed148188a29e6b65fa355b5a667fb22be 100644 (file)
@@ -793,6 +793,15 @@ f_remote_expr(typval_T *argvars UNUSED, typval_T *rettv)
 {
     rettv->v_type = VAR_STRING;
     rettv->vval.v_string = NULL;
+
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL
+               || check_for_opt_string_arg(argvars, 2) == FAIL
+               || (argvars[2].v_type != VAR_UNKNOWN
+                   && check_for_opt_number_arg(argvars, 3) == FAIL)))
+       return;
+
 #ifdef FEAT_CLIENTSERVER
     remote_common(argvars, rettv, TRUE);
 #endif
@@ -891,8 +900,7 @@ f_remote_read(typval_T *argvars UNUSED, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_number_arg(argvars, 1) == FAIL)))
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
        return;
 
     serverid = tv_get_string_chk(&argvars[0]);
@@ -932,6 +940,13 @@ f_remote_send(typval_T *argvars UNUSED, typval_T *rettv)
 {
     rettv->v_type = VAR_STRING;
     rettv->vval.v_string = NULL;
+
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL
+               || check_for_opt_string_arg(argvars, 2) == FAIL))
+       return;
+
 #ifdef FEAT_CLIENTSERVER
     remote_common(argvars, rettv, FALSE);
 #endif
index 9b6d9aa81d3c256b0c365149861a3e5abeb5b69d..362ed77e248cd9cbad8489a9c201fb0e0fc301ef 100644 (file)
@@ -2891,6 +2891,12 @@ f_getcompletion(typval_T *argvars, typval_T *rettv)
     int                options = WILD_SILENT | WILD_USE_NL | WILD_ADD_SLASH
                                                                | WILD_NO_BEEP;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL
+               || check_for_opt_bool_arg(argvars, 2) == FAIL))
+       return;
+
     if (argvars[1].v_type != VAR_STRING)
     {
        semsg(_(e_invarg2), "type must be a string");
index 1b04e62237ac516e1fe2a6e1d0d5d21a2ee2197e..dee95ba37918dbc27d30a3ee3af6d904e45de1af 100644 (file)
@@ -599,8 +599,7 @@ f_histget(typval_T *argvars UNUSED, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_number_arg(argvars, 1) == FAIL)))
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
        return;
 
     str = tv_get_string_chk(&argvars[0]);      // NULL on type error
index f0f045b27288755ca7961c8e9cef6785f6009f10..8bcf28c72f71e9130dcc5b9c572189dee76fb1a6 100644 (file)
@@ -1340,6 +1340,11 @@ dict_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
     char_u     *key;
     dictitem_T *di;
 
+    if (in_vim9script()
+           && (check_for_dict_arg(argvars, 0) == FAIL
+               || check_for_string_or_number_arg(argvars, 1) == FAIL))
+       return;
+
     if (argvars[2].v_type != VAR_UNKNOWN)
        semsg(_(e_toomanyarg), "remove()");
     else if ((d = argvars[0].vval.v_dict) != NULL
index 4c8afb12bd3e1ada130355da7ed012928211a685..59dc658eb7afc03e2395f917942f579681ed3bea 100644 (file)
@@ -3294,9 +3294,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     int                        col;
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars,0) == FAIL
                || check_for_number_arg(argvars, 1) == FAIL))
        return;
 
index af42428c552b256ac6d32ed7d526234782dc3958..c5f8530f5037f7d66552e6fa6d35369c5c8db6a3 100644 (file)
@@ -520,3 +520,9 @@ EXTERN char e_digraph_argument_must_be_one_character_str[]
 EXTERN char e_setdigraphlist_argument_must_be_list_of_lists_with_two_items[]
        INIT(= N_("E1216: setdigraphlist() argument must be a list of lists with two items"));
 #endif
+EXTERN char e_blob_required_for_argument_nr[]
+       INIT(= N_("E1217: Blob required for argument %d"));
+EXTERN char e_chan_or_job_required_for_argument_nr[]
+       INIT(= N_("E1218: Channel or Job required for argument %d"));
+EXTERN char e_job_required_for_argument_nr[]
+       INIT(= N_("E1219: Job required for argument %d"));
index 77774b738da15fae17acdf1d48dc1d6e44929d63..a5c889af87de6715864584ca62feb620ad9b204d 100644 (file)
@@ -4184,6 +4184,15 @@ check_can_index(typval_T *rettv, int evaluate, int verbose)
     void
 f_slice(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+           && ((argvars[0].v_type != VAR_LIST
+                   && argvars[0].v_type != VAR_BLOB
+                   && argvars[0].v_type != VAR_STRING
+                   && check_for_list_arg(argvars, 0) == FAIL)
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_opt_number_arg(argvars, 2) == FAIL))
+       return;
+
     if (check_can_index(argvars, TRUE, FALSE) == OK)
     {
        copy_tv(argvars, rettv);
index 8a6c52d70733dbfdb0d1ccb54338e1936836ce7f..6f552c7193662dcd405414b21abf7d31d5ec0369 100644 (file)
@@ -387,6 +387,12 @@ f_bufnr(typval_T *argvars, typval_T *rettv)
     int                error = FALSE;
     char_u     *name;
 
+    if (in_vim9script()
+           && (check_for_opt_string_or_number_arg(argvars, 0) == FAIL
+               || (argvars[0].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 1) == FAIL)))
+       return;
+
     if (argvars[0].v_type == VAR_UNKNOWN)
        buf = curbuf;
     else
@@ -459,6 +465,12 @@ f_deletebufline(typval_T *argvars, typval_T *rettv)
     tabpage_T  *tp;
     win_T      *wp;
 
+    if (in_vim9script()
+           && (check_for_buffer_arg(argvars, 0) == FAIL
+               || check_for_lnum_arg(argvars, 1) == FAIL
+               || check_for_opt_lnum_arg(argvars, 2) == FAIL))
+       return;
+
     buf = tv_get_buf(&argvars[0], FALSE);
     if (buf == NULL)
     {
@@ -727,6 +739,12 @@ f_getbufline(typval_T *argvars, typval_T *rettv)
     linenr_T   end = 1;
     buf_T      *buf;
 
+    if (in_vim9script()
+           && (check_for_buffer_arg(argvars, 0) == FAIL
+               || check_for_lnum_arg(argvars, 1) == FAIL
+               || check_for_opt_lnum_arg(argvars, 2) == FAIL))
+       return;
+
     buf = tv_get_buf_from_arg(&argvars[0]);
     if (buf != NULL)
     {
index 1a7f427815479c4943634971d2f06dfa619456ef..ad44156bd3af0c3fb8bb87dae60172ff84fb3568 100644 (file)
@@ -300,7 +300,7 @@ arg_bool(type_T *type, argcontext_T *context)
 }
 
 /*
- * Check "type" is a list or a blob.
+ * Check "type" is a list of 'any' or a blob.
  */
     static int
 arg_list_or_blob(type_T *type, argcontext_T *context)
@@ -324,6 +324,33 @@ arg_string_or_nr(type_T *type, argcontext_T *context)
     arg_type_mismatch(&t_string, type, context->arg_idx + 1);
     return FAIL;
 }
+
+/*
+ * Check "type" is a string or a number (buffer)
+ */
+    static int
+arg_buffer(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
+       return OK;
+    arg_type_mismatch(&t_string, type, context->arg_idx + 1);
+    return FAIL;
+}
+
+/*
+ * Check "type" is a string or a number (line)
+ */
+    static int
+arg_lnum(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_STRING || type->tt_type == VAR_NUMBER)
+       return OK;
+    arg_type_mismatch(&t_string, type, context->arg_idx + 1);
+    return FAIL;
+}
+
 /*
  * Check "type" is a string or a list of strings.
  */
@@ -358,6 +385,19 @@ arg_string_or_list_any(type_T *type, argcontext_T *context)
     return FAIL;
 }
 
+/*
+ * Check "type" is a string or a blob
+ */
+    static int
+arg_string_or_blob(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_STRING || type->tt_type == VAR_BLOB)
+       return OK;
+    arg_type_mismatch(&t_string, type, context->arg_idx + 1);
+    return FAIL;
+}
+
 /*
  * Check "type" is a list of 'any' or a dict of 'any'.
  */
@@ -371,6 +411,21 @@ arg_list_or_dict(type_T *type, argcontext_T *context)
     return FAIL;
 }
 
+/*
+ * Check "type" is a list of 'any' or a dict of 'any' or a blob.
+ */
+    static int
+arg_list_or_dict_or_blob(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_ANY
+                    || type->tt_type == VAR_LIST
+                    || type->tt_type == VAR_DICT
+                    || type->tt_type == VAR_BLOB)
+       return OK;
+    arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
+    return FAIL;
+}
+
 /*
  * Check "type" is a job.
  */
@@ -386,8 +441,9 @@ arg_job(type_T *type, argcontext_T *context)
     static int
 arg_chan_or_job(type_T *type, argcontext_T *context)
 {
-    if (type->tt_type == VAR_ANY ||
-           type->tt_type == VAR_CHANNEL || type->tt_type == VAR_JOB)
+    if (type->tt_type == VAR_ANY
+           || type->tt_type == VAR_CHANNEL
+           || type->tt_type == VAR_JOB)
        return OK;
     arg_type_mismatch(&t_channel, type, context->arg_idx + 1);
     return FAIL;
@@ -456,6 +512,20 @@ arg_str_or_nr_or_list(type_T *type, argcontext_T *context)
     return FAIL;
 }
 
+/*
+ * Check "type" is a dict of 'any' or a string
+ */
+    static int
+arg_dict_any_or_string(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_ANY
+               || type->tt_type == VAR_DICT
+               || type->tt_type == VAR_STRING)
+       return OK;
+    arg_type_mismatch(&t_string, type, context->arg_idx + 1);
+    return FAIL;
+}
+
 /*
  * Check "type" which is the third argument of extend().
  */
@@ -471,6 +541,65 @@ arg_extend3(type_T *type, argcontext_T *context)
     return OK;
 }
 
+/*
+ * Check "type" which is the second argument of remove().
+ */
+    static int
+arg_remove2(type_T *type, argcontext_T *context)
+{
+    type_T *first_type = context->arg_types[context->arg_idx - 1];
+
+    if (first_type->tt_type == VAR_LIST || first_type->tt_type == VAR_BLOB)
+       return arg_number(type, context);
+    if (first_type->tt_type == VAR_DICT)
+       return arg_string_or_nr(type, context);
+    return OK;
+}
+
+/*
+ * Check "type" which is the first argument of slice().
+ */
+    static int
+arg_slice1(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_LIST
+           || type->tt_type == VAR_BLOB
+           || type->tt_type == VAR_STRING)
+       return OK;
+
+    arg_type_mismatch(&t_list_any, type, context->arg_idx + 1);
+    return FAIL;
+}
+
+/*
+ * Check "type" which is the first argument of count().
+ */
+    static int
+arg_count1(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_STRING
+           || type->tt_type == VAR_LIST
+           || type->tt_type == VAR_DICT)
+       return OK;
+
+    arg_type_mismatch(&t_string, type, context->arg_idx + 1);
+    return FAIL;
+}
+
+/*
+ * Check "type" which is the first argument of cursor().
+ */
+    static int
+arg_cursor1(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_NUMBER
+           || type->tt_type == VAR_STRING
+           || type->tt_type == VAR_LIST)
+       return OK;
+
+    arg_type_mismatch(&t_number, type, context->arg_idx + 1);
+    return FAIL;
+}
 
 /*
  * Lists of functions that check the argument types of a builtin function.
@@ -481,7 +610,7 @@ static argcheck_T arg1_bool[] = {arg_bool};
 static argcheck_T arg1_dict_any[] = {arg_dict_any};
 static argcheck_T arg1_job[] = {arg_job};
 static argcheck_T arg1_list_any[] = {arg_list_any};
-static argcheck_T arg1_list_nr[] = {arg_list_number};
+static argcheck_T arg1_list_number[] = {arg_list_number};
 static argcheck_T arg1_list_string[] = {arg_list_string};
 static argcheck_T arg1_float_or_nr[] = {arg_float_or_nr};
 static argcheck_T arg1_string_or_nr[] = {arg_string_or_nr};
@@ -490,35 +619,74 @@ static argcheck_T arg1_string_or_list_string[] = {arg_string_or_list_string};
 static argcheck_T arg1_list_or_blob[] = {arg_list_or_blob};
 static argcheck_T arg1_list_or_dict[] = {arg_list_or_dict};
 static argcheck_T arg1_chan_or_job[] = {arg_chan_or_job};
+static argcheck_T arg1_dict_or_string[] = {arg_dict_any_or_string};
 static argcheck_T arg2_float_or_nr[] = {arg_float_or_nr, arg_float_or_nr};
 static argcheck_T arg2_number[] = {arg_number, arg_number};
 static argcheck_T arg2_string[] = {arg_string, arg_string};
 static argcheck_T arg2_string_number[] = {arg_string, arg_number};
 static argcheck_T arg2_list_nr[] = {arg_list_number, arg_list_number};
+static argcheck_T arg2_list_any_string[] = {arg_list_any, arg_string};
+static argcheck_T arg2_list_any_number[] = {arg_list_any, arg_number};
+static argcheck_T arg2_list_number_bool[] = {arg_list_number, arg_bool};
 static argcheck_T arg2_nr_string[] = {arg_number, arg_string};
+static argcheck_T arg2_nr_bool[] = {arg_number, arg_bool};
+static argcheck_T arg2_nr_list[] = {arg_number, arg_list_any};
 static argcheck_T arg2_dict_string[] = {arg_dict_any, arg_string};
 static argcheck_T arg2_dict_string_or_nr[] = {arg_dict_any, arg_string_or_nr};
 static argcheck_T arg2_string_dict[] = {arg_string, arg_dict_any};
-static argcheck_T arg2_string_nr[] = {arg_string, arg_number};
+static argcheck_T arg2_string_list_nr[] = {arg_string, arg_list_number};
 static argcheck_T arg2_string_bool[] = {arg_string, arg_bool};
+static argcheck_T arg2_job_dict[] = {arg_job, arg_dict_any};
+static argcheck_T arg2_job_string_or_number[] = {arg_job, arg_string_or_nr};
 //static argcheck_T arg2_listblob_item[] = {arg_list_or_blob, arg_item_of_prev};
 static argcheck_T arg2_str_or_nr_or_list_dict[] = {arg_str_or_nr_or_list, arg_dict_any};
 static argcheck_T arg2_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
 static argcheck_T arg2_string_or_nr_string[] = {arg_string_or_nr, arg_string};
 static argcheck_T arg2_string_or_nr_nr[] = {arg_string_or_nr, arg_number};
+static argcheck_T arg2_string_or_nr_bool[] = {arg_string_or_nr, arg_bool};
 static argcheck_T arg2_chan_or_job_dict[] = {arg_chan_or_job, arg_dict_any};
+static argcheck_T arg2_chan_or_job_string[] = {arg_chan_or_job, arg_string};
 static argcheck_T arg2_nr_dict_any[] = {arg_number, arg_dict_any};
-//static argcheck_T arg2_string_number[] = {arg_string, arg_number};
 static argcheck_T arg3_string[] = {arg_string, arg_string, arg_string};
 static argcheck_T arg3_number[] = {arg_number, arg_number, arg_number};
+static argcheck_T arg3_number_number_dict[] = {arg_number, arg_number, arg_dict_any};
+static argcheck_T arg3_number_string_any[] = {arg_number, arg_string, NULL};
 static argcheck_T arg3_string_nr_bool[] = {arg_string, arg_number, arg_bool};
 static argcheck_T arg3_string_string_nr[] = {arg_string, arg_string, arg_number};
+static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool};
+static argcheck_T arg3_string_bool_bool[] = {arg_string, arg_bool, arg_bool};
+static argcheck_T arg3_string_bool_dict[] = {arg_string, arg_bool, arg_dict_any};
+static argcheck_T arg3_list_string_dict[] = {arg_list_any, arg_string, arg_dict_any};
+static argcheck_T arg3_dict_number_number[] = {arg_dict_any, arg_number, arg_number};
+static argcheck_T arg3_string_or_nr_nr_bool[] = {arg_string_or_nr, arg_number, arg_bool};
+static argcheck_T arg3_bufnr_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
+static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL};
+static argcheck_T arg5_number[] = {arg_number, arg_number, arg_number, arg_number, arg_number};
+static argcheck_T arg4_browse[] = {arg_bool, arg_string, arg_string, arg_string};
+static argcheck_T arg3_chanexpr[] = {arg_chan_or_job, NULL, arg_dict_any};
+static argcheck_T arg3_chanraw[] = {arg_chan_or_job, arg_string_or_blob, arg_dict_any};
+static argcheck_T arg4_count[] = {arg_count1, NULL, arg_bool, arg_number};
+static argcheck_T arg3_cursor[] = {arg_cursor1, arg_number, arg_number};
+static argcheck_T arg2_deepcopy[] = {NULL, arg_bool};
 static argcheck_T arg2_execute[] = {arg_string_or_list_string, arg_string};
 static argcheck_T arg23_extend[] = {arg_list_or_dict, arg_same_as_prev, arg_extend3};
 static argcheck_T arg23_extendnew[] = {arg_list_or_dict, arg_same_struct_as_prev, arg_extend3};
+static argcheck_T arg4_glob[] = {arg_string, arg_bool, arg_bool, arg_bool};
+static argcheck_T arg5_globpath[] = {arg_string, arg_string, arg_bool, arg_bool, arg_bool};
+static argcheck_T arg4_index[] = {arg_list_or_blob, NULL, arg_number, arg_bool};
 static argcheck_T arg3_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
+static argcheck_T arg4_maparg[] = {arg_string, arg_string, arg_bool, arg_bool};
+static argcheck_T arg4_remote_expr[] = {arg_string, arg_string, arg_string, arg_number};
+static argcheck_T arg3_remove[] = {arg_list_or_dict_or_blob, arg_remove2, arg_number};
 static argcheck_T arg3_setbufline[] = {arg_string_or_nr, arg_string_or_nr, arg_str_or_nr_or_list};
 static argcheck_T arg2_setline[] = {arg_string_or_nr, NULL};
+static argcheck_T arg4_setloclist[] = {arg_number, arg_list_any, arg_string, arg_dict_any};
+static argcheck_T arg3_setqflist[] = {arg_list_any, arg_string, arg_dict_any};
+static argcheck_T arg2_settagstack[] = {arg_number, arg_dict_any, arg_string};
+static argcheck_T arg2_sign_getplaced[] = {arg_string_or_nr, arg_dict_any};
+static argcheck_T arg3_slice[] = {arg_slice1, arg_number, arg_number};
+static argcheck_T arg4_strpart[] = {arg_string, arg_number, arg_number, arg_bool};
+static argcheck_T arg2_term_setansicolors[] = {arg_string_or_nr, arg_list_any};
 static argcheck_T arg23_win_execute[] = {arg_number, arg_string_or_list_string, arg_string};
 static argcheck_T arg4_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number};
 
@@ -866,7 +1034,7 @@ static funcentry_T global_functions[] =
            NULL
 #endif
                        },
-    {"browse",         4, 4, 0,            NULL,
+    {"browse",         4, 4, 0,            arg4_browse,
                        ret_string,         f_browse},
     {"browsedir",      2, 2, 0,            arg2_string,
                        ret_string,         f_browsedir},
@@ -878,7 +1046,7 @@ static funcentry_T global_functions[] =
                        ret_number_bool,    f_bufexists},
     {"buffer_name",    0, 1, FEARG_1,      arg1_string_or_nr,  // obsolete
                        ret_string,         f_bufname},
-    {"buffer_number",  0, 1, FEARG_1,      NULL,       // obsolete
+    {"buffer_number",  0, 1, FEARG_1,      arg2_string_or_nr_bool, // obsolete
                        ret_number,         f_bufnr},
     {"buflisted",      1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number_bool,    f_buflisted},
@@ -888,7 +1056,7 @@ static funcentry_T global_functions[] =
                        ret_number_bool,    f_bufloaded},
     {"bufname",                0, 1, FEARG_1,      arg1_string_or_nr,
                        ret_string,         f_bufname},
-    {"bufnr",          0, 2, FEARG_1,      NULL,
+    {"bufnr",          0, 2, FEARG_1,      arg2_string_or_nr_bool,
                        ret_number,         f_bufnr},
     {"bufwinid",       1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number,         f_bufwinid},
@@ -896,9 +1064,9 @@ static funcentry_T global_functions[] =
                        ret_number,         f_bufwinnr},
     {"byte2line",      1, 1, FEARG_1,      arg1_number,
                        ret_number,         f_byte2line},
-    {"byteidx",                2, 2, FEARG_1,      arg2_string_nr,
+    {"byteidx",                2, 2, FEARG_1,      arg2_string_number,
                        ret_number,         f_byteidx},
-    {"byteidxcomp",    2, 2, FEARG_1,      arg2_string_nr,
+    {"byteidxcomp",    2, 2, FEARG_1,      arg2_string_number,
                        ret_number,         f_byteidxcomp},
     {"call",           2, 3, FEARG_1,      NULL,
                        ret_any,            f_call},
@@ -910,11 +1078,11 @@ static funcentry_T global_functions[] =
                        ret_void,           JOB_FUNC(f_ch_close)},
     {"ch_close_in",    1, 1, FEARG_1,      arg1_chan_or_job,
                        ret_void,           JOB_FUNC(f_ch_close_in)},
-    {"ch_evalexpr",    2, 3, FEARG_1,      NULL,
+    {"ch_evalexpr",    2, 3, FEARG_1,      arg3_chanexpr,
                        ret_any,            JOB_FUNC(f_ch_evalexpr)},
-    {"ch_evalraw",     2, 3, FEARG_1,      NULL,
+    {"ch_evalraw",     2, 3, FEARG_1,      arg3_chanraw,
                        ret_any,            JOB_FUNC(f_ch_evalraw)},
-    {"ch_getbufnr",    2, 2, FEARG_1,      NULL,
+    {"ch_getbufnr",    2, 2, FEARG_1,      arg2_chan_or_job_string,
                        ret_number,         JOB_FUNC(f_ch_getbufnr)},
     {"ch_getjob",      1, 1, FEARG_1,      arg1_chan_or_job,
                        ret_job,            JOB_FUNC(f_ch_getjob)},
@@ -932,9 +1100,9 @@ static funcentry_T global_functions[] =
                        ret_blob,           JOB_FUNC(f_ch_readblob)},
     {"ch_readraw",     1, 2, FEARG_1,      arg2_chan_or_job_dict,
                        ret_string,         JOB_FUNC(f_ch_readraw)},
-    {"ch_sendexpr",    2, 3, FEARG_1,      NULL,
+    {"ch_sendexpr",    2, 3, FEARG_1,      arg3_chanexpr,
                        ret_void,           JOB_FUNC(f_ch_sendexpr)},
-    {"ch_sendraw",     2, 3, FEARG_1,      NULL,
+    {"ch_sendraw",     2, 3, FEARG_1,      arg3_chanraw,
                        ret_void,           JOB_FUNC(f_ch_sendraw)},
     {"ch_setoptions",  2, 2, FEARG_1,      arg2_chan_or_job_dict,
                        ret_void,           JOB_FUNC(f_ch_setoptions)},
@@ -958,9 +1126,9 @@ static funcentry_T global_functions[] =
                        ret_void,           f_clearmatches},
     {"col",            1, 1, FEARG_1,      arg1_string_or_list_any,
                        ret_number,         f_col},
-    {"complete",       2, 2, FEARG_2,      NULL,
+    {"complete",       2, 2, FEARG_2,      arg2_nr_list,
                        ret_void,           f_complete},
-    {"complete_add",   1, 1, FEARG_1,      NULL,
+    {"complete_add",   1, 1, FEARG_1,      arg1_dict_or_string,
                        ret_number,         f_complete_add},
     {"complete_check", 0, 0, 0,            NULL,
                        ret_number_bool,    f_complete_check},
@@ -974,11 +1142,11 @@ static funcentry_T global_functions[] =
                        ret_float,          FLOAT_FUNC(f_cos)},
     {"cosh",           1, 1, FEARG_1,      arg1_float_or_nr,
                        ret_float,          FLOAT_FUNC(f_cosh)},
-    {"count",          2, 4, FEARG_1,      NULL,
+    {"count",          2, 4, FEARG_1,      arg4_count,
                        ret_number,         f_count},
     {"cscope_connection",0,3, 0,           NULL,
                        ret_number,         f_cscope_connection},
-    {"cursor",         1, 3, FEARG_1,      NULL,
+    {"cursor",         1, 3, FEARG_1,      arg3_cursor,
                        ret_number,         f_cursor},
     {"debugbreak",     1, 1, FEARG_1,      arg1_number,
                        ret_number,
@@ -988,11 +1156,11 @@ static funcentry_T global_functions[] =
            NULL
 #endif
                        },
-    {"deepcopy",       1, 2, FEARG_1,      NULL,
+    {"deepcopy",       1, 2, FEARG_1,      arg2_deepcopy,
                        ret_first_arg,      f_deepcopy},
     {"delete",         1, 2, FEARG_1,      arg2_string,
                        ret_number_bool,    f_delete},
-    {"deletebufline",  2, 3, FEARG_1,      NULL,
+    {"deletebufline",  2, 3, FEARG_1,      arg3_bufnr_lnum_lnum,
                        ret_number_bool,    f_deletebufline},
     {"did_filetype",   0, 0, 0,            NULL,
                        ret_number_bool,    f_did_filetype},
@@ -1022,7 +1190,7 @@ static funcentry_T global_functions[] =
                        ret_number_bool,    f_exists},
     {"exp",            1, 1, FEARG_1,      arg1_float_or_nr,
                        ret_float,          FLOAT_FUNC(f_exp)},
-    {"expand",         1, 3, FEARG_1,      NULL,
+    {"expand",         1, 3, FEARG_1,      arg3_string_bool_bool,
                        ret_any,            f_expand},
     {"expandcmd",      1, 1, FEARG_1,      arg1_string,
                        ret_string,         f_expandcmd},
@@ -1044,9 +1212,9 @@ static funcentry_T global_functions[] =
                        ret_string,         f_finddir},
     {"findfile",       1, 3, FEARG_1,      arg3_string_string_nr,
                        ret_string,         f_findfile},
-    {"flatten",                1, 2, FEARG_1,      NULL,
+    {"flatten",                1, 2, FEARG_1,      arg2_list_any_number,
                        ret_list_any,       f_flatten},
-    {"flattennew",     1, 2, FEARG_1,      NULL,
+    {"flattennew",     1, 2, FEARG_1,      arg2_list_any_number,
                        ret_list_any,       f_flattennew},
     {"float2nr",       1, 1, FEARG_1,      arg1_float_or_nr,
                        ret_number,         FLOAT_FUNC(f_float2nr)},
@@ -1082,7 +1250,7 @@ static funcentry_T global_functions[] =
                        ret_any,            f_get},
     {"getbufinfo",     0, 1, FEARG_1,      NULL,
                        ret_list_dict_any,  f_getbufinfo},
-    {"getbufline",     2, 3, FEARG_1,      NULL,
+    {"getbufline",     2, 3, FEARG_1,      arg3_bufnr_lnum_lnum,
                        ret_list_string,    f_getbufline},
     {"getbufvar",      2, 3, FEARG_1,      NULL,
                        ret_any,            f_getbufvar},
@@ -1106,7 +1274,7 @@ static funcentry_T global_functions[] =
                        ret_string,         f_getcmdtype},
     {"getcmdwintype",  0, 0, 0,            NULL,
                        ret_string,         f_getcmdwintype},
-    {"getcompletion",  2, 3, FEARG_1,      NULL,
+    {"getcompletion",  2, 3, FEARG_1,      arg3_string_string_bool,
                        ret_list_string,    f_getcompletion},
     {"getcurpos",      0, 1, FEARG_1,      arg1_number,
                        ret_list_number,    f_getcurpos},
@@ -1150,7 +1318,7 @@ static funcentry_T global_functions[] =
                        ret_list_number,    f_getpos},
     {"getqflist",      0, 1, 0,            arg1_dict_any,
                        ret_list_or_dict_0, f_getqflist},
-    {"getreg",         0, 3, FEARG_1,      NULL,
+    {"getreg",         0, 3, FEARG_1,      arg3_string_bool_bool,
                        ret_getreg,         f_getreg},
     {"getreginfo",     0, 1, FEARG_1,      arg1_string,
                        ret_dict_any,       f_getreginfo},
@@ -1158,9 +1326,9 @@ static funcentry_T global_functions[] =
                        ret_string,         f_getregtype},
     {"gettabinfo",     0, 1, FEARG_1,      arg1_number,
                        ret_list_dict_any,  f_gettabinfo},
-    {"gettabvar",      2, 3, FEARG_1,      NULL,
+    {"gettabvar",      2, 3, FEARG_1,      arg3_number_string_any,
                        ret_any,            f_gettabvar},
-    {"gettabwinvar",   3, 4, FEARG_1,      NULL,
+    {"gettabwinvar",   3, 4, FEARG_1,      arg4_number_number_string_any,
                        ret_any,            f_gettabwinvar},
     {"gettagstack",    0, 1, FEARG_1,      arg1_number,
                        ret_dict_any,       f_gettagstack},
@@ -1174,21 +1342,21 @@ static funcentry_T global_functions[] =
                        ret_number,         f_getwinposx},
     {"getwinposy",     0, 0, 0,            NULL,
                        ret_number,         f_getwinposy},
-    {"getwinvar",      2, 3, FEARG_1,      NULL,
+    {"getwinvar",      2, 3, FEARG_1,      arg3_number_string_any,
                        ret_any,            f_getwinvar},
-    {"glob",           1, 4, FEARG_1,      NULL,
+    {"glob",           1, 4, FEARG_1,      arg4_glob,
                        ret_any,            f_glob},
     {"glob2regpat",    1, 1, FEARG_1,      arg1_string,
                        ret_string,         f_glob2regpat},
-    {"globpath",       2, 5, FEARG_2,      NULL,
+    {"globpath",       2, 5, FEARG_2,      arg5_globpath,
                        ret_any,            f_globpath},
-    {"has",            1, 2, 0,            NULL,
+    {"has",            1, 2, 0,            arg2_string_bool,
                        ret_number_bool,    f_has},
     {"has_key",                2, 2, FEARG_1,      arg2_dict_string_or_nr,
                        ret_number_bool,    f_has_key},
     {"haslocaldir",    0, 2, FEARG_1,      arg2_number,
                        ret_number,         f_haslocaldir},
-    {"hasmapto",       1, 3, FEARG_1,      NULL,
+    {"hasmapto",       1, 3, FEARG_1,      arg3_string_string_bool,
                        ret_number_bool,    f_hasmapto},
     {"highlightID",    1, 1, FEARG_1,      NULL,       // obsolete
                        ret_number,         f_hlID},
@@ -1198,7 +1366,7 @@ static funcentry_T global_functions[] =
                        ret_number_bool,    f_histadd},
     {"histdel",                1, 2, FEARG_1,      NULL,
                        ret_number_bool,    f_histdel},
-    {"histget",                1, 2, FEARG_1,      arg2_string_nr,
+    {"histget",                1, 2, FEARG_1,      arg2_string_number,
                        ret_string,         f_histget},
     {"histnr",         1, 1, FEARG_1,      arg1_string,
                        ret_number,         f_histnr},
@@ -1212,7 +1380,7 @@ static funcentry_T global_functions[] =
                        ret_string,         f_iconv},
     {"indent",         1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number,         f_indent},
-    {"index",          2, 4, FEARG_1,      NULL,
+    {"index",          2, 4, FEARG_1,      arg4_index,
                        ret_number,         f_index},
     {"input",          1, 3, FEARG_1,      arg3_string,
                        ret_string,         f_input},
@@ -1246,15 +1414,15 @@ static funcentry_T global_functions[] =
                        ret_channel,        JOB_FUNC(f_job_getchannel)},
     {"job_info",       0, 1, FEARG_1,      arg1_job,
                        ret_job_info,       JOB_FUNC(f_job_info)},
-    {"job_setoptions", 2, 2, FEARG_1,      NULL,
+    {"job_setoptions", 2, 2, FEARG_1,      arg2_job_dict,
                        ret_void,           JOB_FUNC(f_job_setoptions)},
     {"job_start",      1, 2, FEARG_1,      NULL,
                        ret_job,            JOB_FUNC(f_job_start)},
     {"job_status",     1, 1, FEARG_1,      arg1_job,
                        ret_string,         JOB_FUNC(f_job_status)},
-    {"job_stop",       1, 2, FEARG_1,      NULL,
+    {"job_stop",       1, 2, FEARG_1,      arg2_job_string_or_number,
                        ret_number_bool,    JOB_FUNC(f_job_stop)},
-    {"join",           1, 2, FEARG_1,      NULL,
+    {"join",           1, 2, FEARG_1,      arg2_list_any_string,
                        ret_string,         f_join},
     {"js_decode",      1, 1, FEARG_1,      arg1_string,
                        ret_any,            f_js_decode},
@@ -1274,13 +1442,13 @@ static funcentry_T global_functions[] =
                        ret_string,         f_libcall},
     {"libcallnr",      3, 3, FEARG_3,      NULL,
                        ret_number,         f_libcallnr},
-    {"line",           1, 2, FEARG_1,      arg2_string_nr,
+    {"line",           1, 2, FEARG_1,      arg2_string_number,
                        ret_number,         f_line},
     {"line2byte",      1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number,         f_line2byte},
     {"lispindent",     1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number,         f_lispindent},
-    {"list2str",       1, 2, FEARG_1,      NULL,
+    {"list2str",       1, 2, FEARG_1,      arg2_list_number_bool,
                        ret_string,         f_list2str},
     {"listener_add",   1, 2, FEARG_2,      NULL,
                        ret_number,         f_listener_add},
@@ -1304,13 +1472,13 @@ static funcentry_T global_functions[] =
                        },
     {"map",            2, 2, FEARG_1,      NULL,
                        ret_first_cont,     f_map},
-    {"maparg",         1, 4, FEARG_1,      NULL,
+    {"maparg",         1, 4, FEARG_1,      arg4_maparg,
                        ret_maparg,         f_maparg},
-    {"mapcheck",       1, 3, FEARG_1,      NULL,
+    {"mapcheck",       1, 3, FEARG_1,      arg3_string_string_bool,
                        ret_string,         f_mapcheck},
     {"mapnew",         2, 2, FEARG_1,      NULL,
                        ret_first_cont,     f_mapnew},
-    {"mapset",         3, 3, FEARG_1,      NULL,
+    {"mapset",         3, 3, FEARG_1,      arg3_string_bool_dict,
                        ret_void,           f_mapset},
     {"match",          2, 4, FEARG_1,      arg4_match_func,
                        ret_any,            f_match},
@@ -1324,9 +1492,9 @@ static funcentry_T global_functions[] =
                        ret_number_bool,    f_matchdelete},
     {"matchend",       2, 4, FEARG_1,      arg4_match_func,
                        ret_number,         f_matchend},
-    {"matchfuzzy",     2, 3, FEARG_1,      NULL,
+    {"matchfuzzy",     2, 3, FEARG_1,      arg3_list_string_dict,
                        ret_list_string,    f_matchfuzzy},
-    {"matchfuzzypos",  2, 3, FEARG_1,      NULL,
+    {"matchfuzzypos",  2, 3, FEARG_1,      arg3_list_string_dict,
                        ret_list_any,       f_matchfuzzypos},
     {"matchlist",      2, 4, FEARG_1,      arg4_match_func,
                        ret_list_string,    f_matchlist},
@@ -1360,11 +1528,11 @@ static funcentry_T global_functions[] =
                        },
     {"nextnonblank",   1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number,         f_nextnonblank},
-    {"nr2char",                1, 2, FEARG_1,      NULL,
+    {"nr2char",                1, 2, FEARG_1,      arg2_nr_bool,
                        ret_string,         f_nr2char},
     {"or",             2, 2, FEARG_1,      arg2_number,
                        ret_number,         f_or},
-    {"pathshorten",    1, 2, FEARG_1,      arg2_string_nr,
+    {"pathshorten",    1, 2, FEARG_1,      arg2_string_number,
                        ret_string,         f_pathshorten},
     {"perleval",       1, 1, FEARG_1,      arg1_string,
                        ret_any,
@@ -1430,15 +1598,15 @@ static funcentry_T global_functions[] =
                        ret_void,           JOB_FUNC(f_prompt_setinterrupt)},
     {"prompt_setprompt", 2, 2, FEARG_1,            arg2_string_or_nr_string,
                        ret_void,           JOB_FUNC(f_prompt_setprompt)},
-    {"prop_add",       3, 3, FEARG_1,      NULL,
+    {"prop_add",       3, 3, FEARG_1,      arg3_number_number_dict,
                        ret_void,           PROP_FUNC(f_prop_add)},
-    {"prop_clear",     1, 3, FEARG_1,      NULL,
+    {"prop_clear",     1, 3, FEARG_1,      arg3_number_number_dict,
                        ret_void,           PROP_FUNC(f_prop_clear)},
     {"prop_find",      1, 2, FEARG_1,      arg2_dict_string,
                        ret_dict_any,       PROP_FUNC(f_prop_find)},
     {"prop_list",      1, 2, FEARG_1,      arg2_nr_dict_any,
                        ret_list_dict_any,  PROP_FUNC(f_prop_list)},
-    {"prop_remove",    1, 3, FEARG_1,      NULL,
+    {"prop_remove",    1, 3, FEARG_1,      arg3_dict_number_number,
                        ret_number,         PROP_FUNC(f_prop_remove)},
     {"prop_type_add",  2, 2, FEARG_1,      arg2_string_dict,
                        ret_void,           PROP_FUNC(f_prop_type_add)},
@@ -1478,7 +1646,7 @@ static funcentry_T global_functions[] =
            NULL
 #endif
                        },
-    {"rand",           0, 1, FEARG_1,      arg1_list_nr,
+    {"rand",           0, 1, FEARG_1,      arg1_list_number,
                        ret_number,         f_rand},
     {"range",          1, 3, FEARG_1,      arg3_number,
                        ret_list_number,    f_range},
@@ -1498,23 +1666,23 @@ static funcentry_T global_functions[] =
                        ret_string,         f_reg_recording},
     {"reltime",                0, 2, FEARG_1,      arg2_list_nr,
                        ret_list_any,       f_reltime},
-    {"reltimefloat",   1, 1, FEARG_1,      arg1_list_nr,
+    {"reltimefloat",   1, 1, FEARG_1,      arg1_list_number,
                        ret_float,          FLOAT_FUNC(f_reltimefloat)},
-    {"reltimestr",     1, 1, FEARG_1,      arg1_list_nr,
+    {"reltimestr",     1, 1, FEARG_1,      arg1_list_number,
                        ret_string,         f_reltimestr},
-    {"remote_expr",    2, 4, FEARG_1,      NULL,
+    {"remote_expr",    2, 4, FEARG_1,      arg4_remote_expr,
                        ret_string,         f_remote_expr},
     {"remote_foreground", 1, 1, FEARG_1,    arg1_string,
                        ret_string,         f_remote_foreground},
     {"remote_peek",    1, 2, FEARG_1,      arg2_string,
                        ret_number,         f_remote_peek},
-    {"remote_read",    1, 2, FEARG_1,      arg2_string_nr,
+    {"remote_read",    1, 2, FEARG_1,      arg2_string_number,
                        ret_string,         f_remote_read},
-    {"remote_send",    2, 3, FEARG_1,      NULL,
+    {"remote_send",    2, 3, FEARG_1,      arg3_string,
                        ret_string,         f_remote_send},
     {"remote_startserver", 1, 1, FEARG_1,   arg1_string,
                        ret_void,           f_remote_startserver},
-    {"remove",         2, 3, FEARG_1,      NULL,
+    {"remove",         2, 3, FEARG_1,      arg3_remove,
                        ret_remove,         f_remove},
     {"rename",         2, 2, FEARG_1,      arg2_string,
                        ret_number_bool,    f_rename},
@@ -1552,7 +1720,7 @@ static funcentry_T global_functions[] =
                        ret_number,         f_search},
     {"searchcount",    0, 1, FEARG_1,      arg1_dict_any,
                        ret_dict_any,       f_searchcount},
-    {"searchdecl",     1, 3, FEARG_1,      NULL,
+    {"searchdecl",     1, 3, FEARG_1,      arg3_string_bool_bool,
                        ret_number_bool,    f_searchdecl},
     {"searchpair",     3, 7, 0,            NULL,
                        ret_number,         f_searchpair},
@@ -1570,13 +1738,13 @@ static funcentry_T global_functions[] =
                        ret_void,           f_setbufvar},
     {"setcellwidths",  1, 1, FEARG_1,      arg1_list_any,
                        ret_void,           f_setcellwidths},
-    {"setcharpos",     2, 2, FEARG_2,      NULL,
+    {"setcharpos",     2, 2, FEARG_2,      arg2_string_list_nr,
                        ret_number_bool,    f_setcharpos},
     {"setcharsearch",  1, 1, FEARG_1,      arg1_dict_any,
                        ret_void,           f_setcharsearch},
     {"setcmdpos",      1, 1, FEARG_1,      arg1_number,
                        ret_number_bool,    f_setcmdpos},
-    {"setcursorcharpos", 1, 3, FEARG_1,            NULL,
+    {"setcursorcharpos", 1, 3, FEARG_1,            arg3_cursor,
                        ret_number_bool,    f_setcursorcharpos},
     {"setdigraph",     2, 2, FEARG_1,      arg2_string_number,
                        ret_bool,           f_setdigraph},
@@ -1588,23 +1756,23 @@ static funcentry_T global_functions[] =
                        ret_number_bool,    f_setfperm},
     {"setline",                2, 2, FEARG_2,      arg2_setline,
                        ret_number_bool,    f_setline},
-    {"setloclist",     2, 4, FEARG_2,      NULL,
+    {"setloclist",     2, 4, FEARG_2,      arg4_setloclist,
                        ret_number_bool,    f_setloclist},
-    {"setmatches",     1, 2, FEARG_1,      NULL,
+    {"setmatches",     1, 2, FEARG_1,      arg2_list_any_number,
                        ret_number_bool,    f_setmatches},
-    {"setpos",         2, 2, FEARG_2,      NULL,
+    {"setpos",         2, 2, FEARG_2,      arg2_string_list_nr,
                        ret_number_bool,    f_setpos},
-    {"setqflist",      1, 3, FEARG_1,      NULL,
+    {"setqflist",      1, 3, FEARG_1,      arg3_setqflist,
                        ret_number_bool,    f_setqflist},
     {"setreg",         2, 3, FEARG_2,      NULL,
                        ret_number_bool,    f_setreg},
-    {"settabvar",      3, 3, FEARG_3,      NULL,
+    {"settabvar",      3, 3, FEARG_3,      arg3_number_string_any,
                        ret_void,           f_settabvar},
-    {"settabwinvar",   4, 4, FEARG_4,      NULL,
+    {"settabwinvar",   4, 4, FEARG_4,      arg4_number_number_string_any,
                        ret_void,           f_settabwinvar},
-    {"settagstack",    2, 3, FEARG_2,      NULL,
+    {"settagstack",    2, 3, FEARG_2,      arg2_settagstack,
                        ret_number_bool,    f_settagstack},
-    {"setwinvar",      3, 3, FEARG_3,      NULL,
+    {"setwinvar",      3, 3, FEARG_3,      arg3_number_string_any,
                        ret_void,           f_setwinvar},
     {"sha256",         1, 1, FEARG_1,      arg1_string,
                        ret_string,
@@ -1614,7 +1782,7 @@ static funcentry_T global_functions[] =
            NULL
 #endif
                        },
-    {"shellescape",    1, 2, FEARG_1,      NULL,
+    {"shellescape",    1, 2, FEARG_1,      arg2_string_bool,
                        ret_string,         f_shellescape},
     {"shiftwidth",     0, 1, FEARG_1,      arg1_number,
                        ret_number,         f_shiftwidth},
@@ -1622,7 +1790,7 @@ static funcentry_T global_functions[] =
                        ret_any,            SIGN_FUNC(f_sign_define)},
     {"sign_getdefined",        0, 1, FEARG_1,      arg1_string,
                        ret_list_dict_any,  SIGN_FUNC(f_sign_getdefined)},
-    {"sign_getplaced", 0, 2, FEARG_1,      NULL,
+    {"sign_getplaced", 0, 2, FEARG_1,      arg2_sign_getplaced,
                        ret_list_dict_any,  SIGN_FUNC(f_sign_getplaced)},
     {"sign_jump",      3, 3, FEARG_1,      NULL,
                        ret_number,         SIGN_FUNC(f_sign_jump)},
@@ -1642,7 +1810,7 @@ static funcentry_T global_functions[] =
                        ret_float,          FLOAT_FUNC(f_sin)},
     {"sinh",           1, 1, FEARG_1,      arg1_float_or_nr,
                        ret_float,          FLOAT_FUNC(f_sinh)},
-    {"slice",          2, 3, FEARG_1,      NULL,
+    {"slice",          2, 3, FEARG_1,      arg3_slice,
                        ret_first_arg,      f_slice},
     {"sort",           1, 3, FEARG_1,      NULL,
                        ret_first_arg,      f_sort},
@@ -1658,9 +1826,9 @@ static funcentry_T global_functions[] =
                        ret_string,         f_soundfold},
     {"spellbadword",   0, 1, FEARG_1,      arg1_string,
                        ret_list_string,    f_spellbadword},
-    {"spellsuggest",   1, 3, FEARG_1,      NULL,
+    {"spellsuggest",   1, 3, FEARG_1,      arg3_string_nr_bool,
                        ret_list_string,    f_spellsuggest},
-    {"split",          1, 3, FEARG_1,      NULL,
+    {"split",          1, 3, FEARG_1,      arg3_string_string_bool,
                        ret_list_string,    f_split},
     {"sqrt",           1, 1, FEARG_1,      arg1_float_or_nr,
                        ret_float,          FLOAT_FUNC(f_sqrt)},
@@ -1676,13 +1844,13 @@ static funcentry_T global_functions[] =
                        ret_number,         f_str2nr},
     {"strcharlen",     1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number,         f_strcharlen},
-    {"strcharpart",    2, 4, FEARG_1,      NULL,
+    {"strcharpart",    2, 4, FEARG_1,      arg4_strpart,
                        ret_string,         f_strcharpart},
     {"strchars",       1, 2, FEARG_1,      arg2_string_bool,
                        ret_number,         f_strchars},
-    {"strdisplaywidth",        1, 2, FEARG_1,      arg2_string_nr,
+    {"strdisplaywidth",        1, 2, FEARG_1,      arg2_string_number,
                        ret_number,         f_strdisplaywidth},
-    {"strftime",       1, 2, FEARG_1,      arg2_string_nr,
+    {"strftime",       1, 2, FEARG_1,      arg2_string_number,
                        ret_string,
 #ifdef HAVE_STRFTIME
            f_strftime
@@ -1690,7 +1858,7 @@ static funcentry_T global_functions[] =
            NULL
 #endif
                        },
-    {"strgetchar",     2, 2, FEARG_1,      arg2_string_nr,
+    {"strgetchar",     2, 2, FEARG_1,      arg2_string_number,
                        ret_number,         f_strgetchar},
     {"stridx",         2, 3, FEARG_1,      arg3_string_string_nr,
                        ret_number,         f_stridx},
@@ -1698,7 +1866,7 @@ static funcentry_T global_functions[] =
                        ret_string,         f_string},
     {"strlen",         1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_number,         f_strlen},
-    {"strpart",                2, 4, FEARG_1,      NULL,
+    {"strpart",                2, 4, FEARG_1,      arg4_strpart,
                        ret_string,         f_strpart},
     {"strptime",       2, 2, FEARG_1,      arg2_string,
                        ret_number,
@@ -1714,7 +1882,7 @@ static funcentry_T global_functions[] =
                        ret_string,         f_strtrans},
     {"strwidth",       1, 1, FEARG_1,      arg1_string,
                        ret_number,         f_strwidth},
-    {"submatch",       1, 2, FEARG_1,      NULL,
+    {"submatch",       1, 2, FEARG_1,      arg2_nr_bool,
                        ret_string,         f_submatch},
     {"substitute",     4, 4, FEARG_1,      NULL,
                        ret_string,         f_substitute},
@@ -1722,7 +1890,7 @@ static funcentry_T global_functions[] =
                        ret_dict_any,       f_swapinfo},
     {"swapname",       1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_string,         f_swapname},
-    {"synID",          3, 3, 0,            NULL,
+    {"synID",          3, 3, 0,            arg3_string_or_nr_nr_bool,
                        ret_number,         f_synID},
     {"synIDattr",      2, 3, FEARG_1,      NULL,
                        ret_string,         f_synIDattr},
@@ -1784,7 +1952,7 @@ static funcentry_T global_functions[] =
                        ret_string,         TERM_FUNC(f_term_getstatus)},
     {"term_gettitle",  1, 1, FEARG_1,      arg1_string_or_nr,
                        ret_string,         TERM_FUNC(f_term_gettitle)},
-    {"term_gettty",    1, 2, FEARG_1,      NULL,
+    {"term_gettty",    1, 2, FEARG_1,      arg2_string_or_nr_bool,
                        ret_string,         TERM_FUNC(f_term_gettty)},
     {"term_list",      0, 0, 0,            NULL,
                        ret_list_number,    TERM_FUNC(f_term_list)},
@@ -1792,7 +1960,7 @@ static funcentry_T global_functions[] =
                        ret_list_dict_any,  TERM_FUNC(f_term_scrape)},
     {"term_sendkeys",  2, 2, FEARG_1,      arg2_string_or_nr_string,
                        ret_void,           TERM_FUNC(f_term_sendkeys)},
-    {"term_setansicolors", 2, 2, FEARG_1,   NULL,
+    {"term_setansicolors", 2, 2, FEARG_1,   arg2_term_setansicolors,
                        ret_void,
 #if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
            f_term_setansicolors
@@ -1828,7 +1996,7 @@ static funcentry_T global_functions[] =
                        ret_number,         f_test_getvalue},
     {"test_gui_drop_files",    4, 4, 0,            NULL,
                        ret_void,           f_test_gui_drop_files},
-    {"test_gui_mouse_event",   5, 5, 0,            NULL,
+    {"test_gui_mouse_event",   5, 5, 0,    arg5_number,
                        ret_void,           f_test_gui_mouse_event},
     {"test_ignore_error", 1, 1, FEARG_1,    arg1_string,
                        ret_void,           f_test_ignore_error},
@@ -1850,7 +2018,7 @@ static funcentry_T global_functions[] =
                        ret_string,         f_test_null_string},
     {"test_option_not_set", 1, 1, FEARG_1,  arg1_string,
                        ret_void,           f_test_option_not_set},
-    {"test_override",  2, 2, FEARG_2,      arg2_string_nr,
+    {"test_override",  2, 2, FEARG_2,      arg2_string_number,
                        ret_void,           f_test_override},
     {"test_refcount",  1, 1, FEARG_1,      NULL,
                        ret_number,         f_test_refcount},
@@ -1874,7 +2042,7 @@ static funcentry_T global_functions[] =
                        ret_void,           f_test_void},
     {"timer_info",     0, 1, FEARG_1,      arg1_number,
                        ret_list_dict_any,  TIMER_FUNC(f_timer_info)},
-    {"timer_pause",    2, 2, FEARG_1,      NULL,
+    {"timer_pause",    2, 2, FEARG_1,      arg2_nr_bool,
                        ret_void,           TIMER_FUNC(f_timer_pause)},
     {"timer_start",    2, 3, FEARG_1,      NULL,
                        ret_number,         TIMER_FUNC(f_timer_start)},
@@ -1926,7 +2094,7 @@ static funcentry_T global_functions[] =
                        ret_number,         f_win_id2win},
     {"win_screenpos",  1, 1, FEARG_1,      arg1_number,
                        ret_list_number,    f_win_screenpos},
-    {"win_splitmove",   2, 3, FEARG_1,     NULL,
+    {"win_splitmove",   2, 3, FEARG_1,     arg3_number_number_dict,
                        ret_number_bool,    f_win_splitmove},
     {"winbufnr",       1, 1, FEARG_1,      arg1_number,
                        ret_number,         f_winbufnr},
@@ -2494,8 +2662,7 @@ f_char2nr(typval_T *argvars, typval_T *rettv)
 {
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_bool_arg(argvars, 1) == FAIL)))
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
        return;
 
     if (has_mbyte)
@@ -2679,6 +2846,15 @@ set_cursorpos(typval_T *argvars, typval_T *rettv, int charcol)
     long       coladd = 0;
     int                set_curswant = TRUE;
 
+    if (in_vim9script()
+           && ((argvars[0].v_type != VAR_NUMBER
+                   && argvars[0].v_type != VAR_STRING
+                   && argvars[0].v_type != VAR_LIST
+                   && check_for_number_arg(argvars, 0) == FAIL)
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_opt_number_arg(argvars, 2) == FAIL))
+       return;
+
     rettv->vval.v_number = -1;
     if (argvars[0].v_type == VAR_LIST)
     {
@@ -2785,6 +2961,10 @@ f_deepcopy(typval_T *argvars, typval_T *rettv)
     varnumber_T        noref = 0;
     int                copyID;
 
+    if (in_vim9script()
+           && (check_for_opt_bool_arg(argvars, 1) == FAIL))
+       return;
+
     if (argvars[1].v_type != VAR_UNKNOWN)
        noref = tv_get_bool_chk(&argvars[1], NULL);
     if (noref < 0 || noref > 1)
@@ -3234,7 +3414,16 @@ f_expand(typval_T *argvars, typval_T *rettv)
     char_u     *result;
 #ifdef BACKSLASH_IN_FILENAME
     char_u     *p_csl_save = p_csl;
+#endif
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 2) == FAIL)))
+       return;
+
+#ifdef BACKSLASH_IN_FILENAME
     // avoid using 'completeslash' here
     p_csl = empty_option;
 #endif
@@ -4132,6 +4321,13 @@ f_getreg(typval_T *argvars, typval_T *rettv)
     int                return_list = FALSE;
     int                error = FALSE;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 2) == FAIL)))
+       return;
+
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
        strregname = tv_get_string_chk(&argvars[0]);
@@ -5414,6 +5610,11 @@ f_has(typval_T *argvars, typval_T *rettv)
        {NULL, 0}
     };
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
+       return;
+
     name = tv_get_string(&argvars[0]);
     for (i = 0; has_list[i].name != NULL; ++i)
        if (STRICMP(name, has_list[i].name) == 0)
@@ -5702,6 +5903,13 @@ f_hasmapto(typval_T *argvars, typval_T *rettv)
     char_u     buf[NUMBUFLEN];
     int                abbr = FALSE;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_string_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 2) == FAIL)))
+       return;
+
     name = tv_get_string(&argvars[0]);
     if (argvars[1].v_type == VAR_UNKNOWN)
        mode = (char_u *)"nvo";
@@ -5763,6 +5971,16 @@ f_index(typval_T *argvars, typval_T *rettv)
     int                error = FALSE;
 
     rettv->vval.v_number = -1;
+
+    if (in_vim9script()
+           && ((argvars[0].v_type != VAR_LIST
+                   && argvars[0].v_type != VAR_BLOB
+                   && check_for_list_arg(argvars, 0) == FAIL)
+               || check_for_opt_number_arg(argvars, 2) == FAIL
+               || (argvars[2].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 3) == FAIL)))
+       return;
+
     if (argvars[0].v_type == VAR_BLOB)
     {
        typval_T        tv;
@@ -6180,8 +6398,7 @@ f_line(typval_T *argvars, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_number_arg(argvars, 1) == FAIL)))
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
        return;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
@@ -6254,6 +6471,15 @@ f_luaeval(typval_T *argvars, typval_T *rettv)
     static void
 f_maparg(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_string_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && (check_for_opt_bool_arg(argvars, 2) == FAIL
+                       || (argvars[2].v_type != VAR_UNKNOWN
+                           && check_for_opt_bool_arg(argvars, 3) == FAIL)))))
+               return;
+
     get_maparg(argvars, rettv, TRUE);
 }
 
@@ -6263,6 +6489,13 @@ f_maparg(typval_T *argvars, typval_T *rettv)
     static void
 f_mapcheck(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_string_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 2) == FAIL)))
+       return;
+
     get_maparg(argvars, rettv, FALSE);
 }
 
@@ -6331,11 +6564,10 @@ find_some_match(typval_T *argvars, typval_T *rettv, matchtype_T type)
            && ((argvars[0].v_type != VAR_STRING
                    && argvars[0].v_type != VAR_LIST
                    && check_for_string_arg(argvars, 0) == FAIL)
-               || (check_for_string_arg(argvars, 1) == FAIL)
+               || check_for_string_arg(argvars, 1) == FAIL
+               || check_for_opt_number_arg(argvars, 2) == FAIL
                || (argvars[2].v_type != VAR_UNKNOWN
-                   && (check_for_number_arg(argvars, 2) == FAIL
-                       || (argvars[3].v_type != VAR_UNKNOWN
-                           && check_for_number_arg(argvars, 3) == FAIL)))))
+                   && check_for_opt_number_arg(argvars, 3) == FAIL)))
        goto theend;
 
     if (argvars[0].v_type == VAR_LIST)
@@ -6716,6 +6948,11 @@ f_nr2char(typval_T *argvars, typval_T *rettv)
 {
     char_u     buf[NUMBUFLEN];
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
+       return;
+
     if (has_mbyte)
     {
        int     utf8 = 0;
@@ -7690,6 +7927,13 @@ f_searchdecl(typval_T *argvars, typval_T *rettv)
 
     rettv->vval.v_number = 1;  // default: FAIL
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 2) == FAIL)))
+       return;
+
     name = tv_get_string_chk(&argvars[0]);
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
@@ -8038,6 +8282,11 @@ set_position(typval_T *argvars, typval_T *rettv, int charpos)
 
     rettv->vval.v_number = -1;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_list_arg(argvars, 1) == FAIL))
+       return;
+
     name = tv_get_string_chk(argvars);
     if (name != NULL)
     {
@@ -8401,6 +8650,12 @@ f_settagstack(typval_T *argvars, typval_T *rettv)
 
     rettv->vval.v_number = -1;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_dict_arg(argvars, 1) == FAIL
+               || check_for_opt_string_arg(argvars, 2) == FAIL))
+       return;
+
     // first argument: window number or id
     wp = find_win_by_nr_or_id(&argvars[0]);
     if (wp == NULL)
@@ -8467,8 +8722,14 @@ f_sha256(typval_T *argvars, typval_T *rettv)
     static void
 f_shellescape(typval_T *argvars, typval_T *rettv)
 {
-    int do_special = non_zero_arg(&argvars[1]);
+    int do_special;
+
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
+       return;
 
+    do_special = non_zero_arg(&argvars[1]);
     rettv->vval.v_string = vim_strsave_shellescape(
                           tv_get_string(&argvars[0]), do_special, do_special);
     rettv->v_type = VAR_STRING;
@@ -8610,6 +8871,13 @@ f_spellsuggest(typval_T *argvars UNUSED, typval_T *rettv)
     int                need_capital = FALSE;
     int                wo_spell_save = curwin->w_p_spell;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_number_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 2) == FAIL)))
+       return;
+
     if (!curwin->w_p_spell)
     {
        did_set_spelllang(curwin);
@@ -8688,6 +8956,13 @@ f_split(typval_T *argvars, typval_T *rettv)
     int                keepempty = FALSE;
     int                typeerr = FALSE;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_string_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 2) == FAIL)))
+       return;
+
     // Make 'cpoptions' empty, the 'l' flag should not be used here.
     save_cpo = p_cpo;
     p_cpo = empty_option;
@@ -8758,6 +9033,11 @@ f_submatch(typval_T *argvars, typval_T *rettv)
     int                no;
     int                retList = 0;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
+       return;
+
     no = (int)tv_get_number_chk(&argvars[0], &error);
     if (error)
        return;
@@ -8852,6 +9132,12 @@ f_synID(typval_T *argvars UNUSED, typval_T *rettv)
     int                trans;
     int                transerr = FALSE;
 
+    if (in_vim9script()
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_bool_arg(argvars, 2) == FAIL))
+       return;
+
     lnum = tv_get_lnum(argvars);               // -1 on type error
     col = (linenr_T)tv_get_number(&argvars[1]) - 1;    // -1 on type error
     trans = (int)tv_get_bool_chk(&argvars[2], &transerr);
@@ -8996,9 +9282,7 @@ f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv)
     rettv_list_set(rettv, NULL);
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
                || check_for_number_arg(argvars, 1) == FAIL))
        return;
 
@@ -9059,9 +9343,7 @@ f_synstack(typval_T *argvars UNUSED, typval_T *rettv)
     rettv_list_set(rettv, NULL);
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
                || check_for_number_arg(argvars, 1) == FAIL))
        return;
 
index d0bbff79224afdcca9eb7a2ed238a7a08e103d73..909ee1d2c2550f140873ca0ca864db7e49806c47 100644 (file)
@@ -4039,6 +4039,11 @@ f_gettabvar(typval_T *argvars, typval_T *rettv)
     rettv->v_type = VAR_STRING;
     rettv->vval.v_string = NULL;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL))
+       return;
+
     varname = tv_get_string_chk(&argvars[1]);
     tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
     if (tp != NULL && varname != NULL)
@@ -4073,6 +4078,12 @@ f_gettabvar(typval_T *argvars, typval_T *rettv)
     void
 f_gettabwinvar(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_string_arg(argvars, 2) == FAIL))
+       return;
+
     getwinvar(argvars, rettv, 1);
 }
 
@@ -4082,6 +4093,11 @@ f_gettabwinvar(typval_T *argvars, typval_T *rettv)
     void
 f_getwinvar(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL))
+       return;
+
     getwinvar(argvars, rettv, 0);
 }
 
@@ -4165,6 +4181,11 @@ f_settabvar(typval_T *argvars, typval_T *rettv UNUSED)
     if (check_secure())
        return;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL))
+       return;
+
     tp = find_tabpage((int)tv_get_number_chk(&argvars[0], NULL));
     varname = tv_get_string_chk(&argvars[1]);
     varp = &argvars[2];
@@ -4195,6 +4216,12 @@ f_settabvar(typval_T *argvars, typval_T *rettv UNUSED)
     void
 f_settabwinvar(typval_T *argvars, typval_T *rettv UNUSED)
 {
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_string_arg(argvars, 2) == FAIL))
+       return;
+
     setwinvar(argvars, 1);
 }
 
@@ -4204,6 +4231,11 @@ f_settabwinvar(typval_T *argvars, typval_T *rettv UNUSED)
     void
 f_setwinvar(typval_T *argvars, typval_T *rettv UNUSED)
 {
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL))
+       return;
+
     setwinvar(argvars, 0);
 }
 
index 329413d0bdfb15086a4ffdd5ef4a0b4c85891ef6..d47680c7592830918d8c2891179118020e4c0766 100644 (file)
@@ -655,8 +655,7 @@ f_tabpagewinnr(typval_T *argvars UNUSED, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_number_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_string_arg(argvars, 1) == FAIL)))
+               || check_for_opt_string_arg(argvars, 1) == FAIL))
        return;
 
     tp = find_tabpage((int)tv_get_number(&argvars[0]));
@@ -834,6 +833,12 @@ f_win_splitmove(typval_T *argvars, typval_T *rettv)
     win_T   *targetwin;
     int     flags = 0, size = 0;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_opt_dict_arg(argvars, 2) == FAIL))
+       return;
+
     wp = find_win_by_nr_or_id(&argvars[0]);
     targetwin = find_win_by_nr_or_id(&argvars[1]);
 
index 40b5761aeee218460f6cd8fa0d0027d834aeaa65..0d59a6b4f88b21d0c5e6dd2fa8cb7e973ae40e09 100644 (file)
@@ -1254,6 +1254,15 @@ f_glob(typval_T *argvars, typval_T *rettv)
     expand_T   xpc;
     int                error = FALSE;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && (check_for_opt_bool_arg(argvars, 2) == FAIL
+                       || (argvars[2].v_type != VAR_UNKNOWN
+                           && check_for_opt_bool_arg(argvars, 3) == FAIL)))))
+       return;
+
     // When the optional second argument is non-zero, don't remove matches
     // for 'wildignore' and don't put matches for 'suffixes' at the end.
     rettv->v_type = VAR_STRING;
@@ -1318,11 +1327,23 @@ f_globpath(typval_T *argvars, typval_T *rettv)
 {
     int                flags = WILD_IGNORE_COMPLETESLASH;
     char_u     buf1[NUMBUFLEN];
-    char_u     *file = tv_get_string_buf_chk(&argvars[1], buf1);
+    char_u     *file;
     int                error = FALSE;
     garray_T   ga;
     int                i;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL
+               || check_for_opt_bool_arg(argvars, 2) == FAIL
+               || (argvars[2].v_type != VAR_UNKNOWN
+                   && (check_for_opt_bool_arg(argvars, 3) == FAIL
+                       || (argvars[3].v_type != VAR_UNKNOWN
+                           && check_for_opt_bool_arg(argvars, 4) == FAIL)))))
+       return;
+
+    file = tv_get_string_buf_chk(&argvars[1], buf1);
+
     // When the optional second argument is non-zero, don't remove matches
     // for 'wildignore' and don't put matches for 'suffixes' at the end.
     rettv->v_type = VAR_STRING;
@@ -1449,8 +1470,7 @@ f_pathshorten(typval_T *argvars, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_number_arg(argvars, 1) == FAIL)))
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
        return;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
@@ -2423,10 +2443,12 @@ f_browse(typval_T *argvars UNUSED, typval_T *rettv)
     int                error = FALSE;
 
     if (in_vim9script()
-           && (check_for_string_arg(argvars, 1) == FAIL
+           && (check_for_bool_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL
                || check_for_string_arg(argvars, 2) == FAIL
                || check_for_string_arg(argvars, 3) == FAIL))
        return;
+
     save = (int)tv_get_number_chk(&argvars[0], &error);
     title = tv_get_string_chk(&argvars[1]);
     initdir = tv_get_string_buf_chk(&argvars[2], buf);
index 5f1b774cc7e88b751be3d04b477c852766de3ac1..6a157085605d4270889b65da2d75c500506e2e0b 100644 (file)
@@ -1700,10 +1700,11 @@ EXTERN char e_readonlyvar[]     INIT(= N_("E46: Cannot change read-only variable \"%
 EXTERN char e_readonlysbx[]    INIT(= N_("E794: Cannot set variable in the sandbox: \"%s\""));
 EXTERN char e_stringreq[]      INIT(= N_("E928: String required"));
 EXTERN char e_numberreq[]      INIT(= N_("E889: Number required"));
-EXTERN char e_boolreq[]                INIT(= N_("E839: Number required"));
+EXTERN char e_boolreq[]                INIT(= N_("E839: Bool required"));
 EXTERN char e_emptykey[]       INIT(= N_("E713: Cannot use empty key for Dictionary"));
 EXTERN char e_dictreq[]                INIT(= N_("E715: Dictionary required"));
 EXTERN char e_listidx[]                INIT(= N_("E684: list index out of range: %ld"));
+EXTERN char e_blobreq[]                INIT(= N_("E538: Dictionary required"));
 EXTERN char e_blobidx[]                INIT(= N_("E979: Blob index out of range: %ld"));
 EXTERN char e_invalblob[]      INIT(= N_("E978: Invalid operation for Blob"));
 EXTERN char e_toomanyarg[]     INIT(= N_("E118: Too many arguments for function: %s"));
@@ -1810,6 +1811,8 @@ EXTERN char e_lock_unlock[]       INIT(= N_("E940: Cannot lock or unlock variable %s")
 #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
 EXTERN char e_alloc_color[]    INIT(= N_("E254: Cannot allocate color %s"));
 #endif
+EXTERN char e_chan_or_job_req[]        INIT(= N_("E706: Channel or Job required"));
+EXTERN char e_jobreq[]         INIT(= N_("E693: Job required"));
 
 EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));
 EXTERN char bot_top_msg[] INIT(= N_("search hit BOTTOM, continuing at TOP"));
index 9bbf1233cfc7e909ff731fe67cfad0df23d8c0b9..1eebfd281b011f024163cdfdf058cd363dbca4aa 100644 (file)
@@ -2436,6 +2436,11 @@ f_complete(typval_T *argvars, typval_T *rettv UNUSED)
     int            startcol;
     int            save_textlock = textlock;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_list_arg(argvars, 1) == FAIL))
+       return;
+
     if ((State & INSERT) == 0)
     {
        emsg(_("E785: complete() can only be used in Insert mode"));
@@ -2468,6 +2473,12 @@ f_complete(typval_T *argvars, typval_T *rettv UNUSED)
     void
 f_complete_add(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+           && (argvars[0].v_type != VAR_DICT
+               && argvars[0].v_type != VAR_STRING
+               && check_for_string_arg(argvars, 0) == FAIL))
+       return;
+
     rettv->vval.v_number = ins_compl_add_tv(&argvars[0], 0, FALSE);
 }
 
index 1271c779dad78ddc9ef44576689f05de40f2417f..7607f7be56a24654ee44362d7d91b575b805d920 100644 (file)
--- a/src/job.c
+++ b/src/job.c
@@ -1726,9 +1726,7 @@ f_prompt_setprompt(typval_T *argvars, typval_T *rettv UNUSED)
     char_u     *text;
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
                || check_for_string_arg(argvars, 1) == FAIL))
        return;
 
@@ -1875,9 +1873,15 @@ f_job_info(typval_T *argvars, typval_T *rettv)
     void
 f_job_setoptions(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    job_T      *job = get_job_arg(&argvars[0]);
+    job_T      *job;
     jobopt_T   opt;
 
+    if (in_vim9script()
+           && (check_for_job_arg(argvars, 0) == FAIL
+               || check_for_dict_arg(argvars, 1) == FAIL))
+       return;
+
+    job = get_job_arg(&argvars[0]);
     if (job == NULL)
        return;
     clear_job_options(&opt);
@@ -1928,8 +1932,14 @@ f_job_status(typval_T *argvars, typval_T *rettv)
     void
 f_job_stop(typval_T *argvars, typval_T *rettv)
 {
-    job_T      *job = get_job_arg(&argvars[0]);
+    job_T      *job;
+
+    if (in_vim9script()
+           && (check_for_job_arg(argvars, 0) == FAIL
+               || check_for_opt_string_or_number_arg(argvars, 1) == FAIL))
+       return;
 
+    job = get_job_arg(&argvars[0]);
     if (job != NULL)
        rettv->vval.v_number = job_stop(job, argvars, NULL);
 }
index 417f735e0dba4f44c1488782da82d921a55ed0a9..4b9236a2908e114e663e013907e1b756064a2fa6 100644 (file)
@@ -823,6 +823,11 @@ flatten_common(typval_T *argvars, typval_T *rettv, int make_copy)
     long    maxdepth;
     int            error = FALSE;
 
+    if (in_vim9script()
+           && (check_for_list_arg(argvars, 0) == FAIL
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
+       return;
+
     if (argvars[0].v_type != VAR_LIST)
     {
        semsg(_(e_listarg), "flatten()");
@@ -1267,6 +1272,11 @@ f_join(typval_T *argvars, typval_T *rettv)
     garray_T   ga;
     char_u     *sep;
 
+    if (in_vim9script()
+           && (check_for_list_arg(argvars, 0) == FAIL
+               || check_for_opt_string_arg(argvars, 1) == FAIL))
+       return;
+
     if (argvars[0].v_type != VAR_LIST)
     {
        emsg(_(e_listreq));
@@ -1470,6 +1480,12 @@ f_list2str(typval_T *argvars, typval_T *rettv)
 
     rettv->v_type = VAR_STRING;
     rettv->vval.v_string = NULL;
+
+    if (in_vim9script()
+           && (check_for_list_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
+       return;
+
     if (argvars[0].v_type != VAR_LIST)
     {
        emsg(_(e_invarg));
@@ -1522,6 +1538,12 @@ list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
     int                error = FALSE;
     long       idx;
 
+    if (in_vim9script()
+           && (check_for_list_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_opt_number_arg(argvars, 2) == FAIL))
+       return;
+
     if ((l = argvars[0].vval.v_list) == NULL
                             || value_check_lock(l->lv_lock, arg_errmsg, TRUE))
        return;
@@ -2489,6 +2511,16 @@ f_count(typval_T *argvars, typval_T *rettv)
     int                ic = FALSE;
     int                error = FALSE;
 
+    if (in_vim9script()
+           && ((argvars[0].v_type != VAR_STRING
+                   && argvars[0].v_type != VAR_LIST
+                   && argvars[0].v_type != VAR_DICT
+                   && check_for_string_arg(argvars, 0) == FAIL)
+               || check_for_opt_bool_arg(argvars, 2) == FAIL
+               || (argvars[2].v_type != VAR_UNKNOWN
+                   && check_for_opt_number_arg(argvars, 3) == FAIL)))
+       return;
+
     if (argvars[2].v_type != VAR_UNKNOWN)
        ic = (int)tv_get_bool_chk(&argvars[2], &error);
 
index 1f935ba0efcac5054e5282d328fb2c7a242d2149..9f80ba84558612dcc61a7ce61ecd60def5956e60 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -2316,6 +2316,12 @@ f_mapset(typval_T *argvars, typval_T *rettv UNUSED)
     int                nowait;
     char_u     *arg;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_bool_arg(argvars, 1) == FAIL
+               || check_for_dict_arg(argvars, 2) == FAIL))
+       return;
+
     which = tv_get_string_buf_chk(&argvars[0], buf);
     if (which == NULL)
        return;
index f383d8a1a60143ea37b8c6a0d32507c2604a6f8e..741488a08d6368d0bb414c2cb99a6e14e2220dd1 100644 (file)
@@ -1045,14 +1045,21 @@ f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     listitem_T *li;
     dict_T     *d;
     list_T     *s = NULL;
-    win_T      *win = get_optional_window(argvars, 1);
+    win_T      *win;
 
     rettv->vval.v_number = -1;
+
+    if (in_vim9script()
+           && (check_for_list_arg(argvars, 0) == FAIL
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
+       return;
+
     if (argvars[0].v_type != VAR_LIST)
     {
        emsg(_(e_listreq));
        return;
     }
+    win = get_optional_window(argvars, 1);
     if (win == NULL)
        return;
 
index ccde9a6b68e03d026824bd7e2db28d88d2da8631..c673db3872efa26d4c91febe4eed0c5d508d31a0 100644 (file)
@@ -11,10 +11,24 @@ varnumber_T tv_get_bool_chk(typval_T *varp, int *denote);
 float_T tv_get_float(typval_T *varp);
 int check_for_string_arg(typval_T *args, int idx);
 int check_for_nonempty_string_arg(typval_T *args, int idx);
+int check_for_opt_string_arg(typval_T *args, int idx);
 int check_for_number_arg(typval_T *args, int idx);
+int check_for_opt_number_arg(typval_T *args, int idx);
 int check_for_bool_arg(typval_T *args, int idx);
+int check_for_opt_bool_arg(typval_T *args, int idx);
 int check_for_list_arg(typval_T *args, int idx);
+int check_for_opt_list_arg(typval_T *args, int idx);
 int check_for_dict_arg(typval_T *args, int idx);
+int check_for_opt_dict_arg(typval_T *args, int idx);
+int check_for_blob_arg(typval_T *args, int idx);
+int check_for_chan_or_job_arg(typval_T *args, int idx);
+int check_for_job_arg(typval_T *args, int idx);
+int check_for_string_or_number_arg(typval_T *args, int idx);
+int check_for_buffer_arg(typval_T *args, int idx);
+int check_for_lnum_arg(typval_T *args, int idx);
+int check_for_opt_lnum_arg(typval_T *args, int idx);
+int check_for_opt_string_or_number_arg(typval_T *args, int idx);
+int check_for_string_or_blob_arg(typval_T *args, int idx);
 char_u *tv_get_string(typval_T *varp);
 char_u *tv_get_string_strict(typval_T *varp);
 char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
index 39424ca68061f6ad2c32d5fd5d402e1db63eb1a6..eb1a4a8edef0d5b730a1ae9760fbd7cfd168a1b4 100644 (file)
@@ -8466,6 +8466,14 @@ f_setloclist(typval_T *argvars, typval_T *rettv)
 
     rettv->vval.v_number = -1;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_list_arg(argvars, 1) == FAIL
+               || check_for_opt_string_arg(argvars, 2) == FAIL
+               || (argvars[2].v_type != VAR_UNKNOWN
+                   && check_for_opt_dict_arg(argvars, 3) == FAIL)))
+       return;
+
     win = find_win_by_nr_or_id(&argvars[0]);
     if (win != NULL)
        set_qf_ll_list(win, &argvars[1], &argvars[2], &argvars[3], rettv);
@@ -8477,6 +8485,13 @@ f_setloclist(typval_T *argvars, typval_T *rettv)
     void
 f_setqflist(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+           && (check_for_list_arg(argvars, 0) == FAIL
+               || check_for_opt_string_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_dict_arg(argvars, 2) == FAIL)))
+       return;
+
     set_qf_ll_list(NULL, &argvars[0], &argvars[1], &argvars[2], rettv);
 }
 #endif
index bbf67d5ce05c935c407647227d3d019d5b72569c..483265e29d3a0f8d5f0cbe4c793d3073ac95cf81 100644 (file)
@@ -1217,7 +1217,8 @@ first_submatch(regmmatch_T *rp)
 do_search(
     oparg_T        *oap,       // can be NULL
     int                    dirc,       // '/' or '?'
-    int                    search_delim, // the delimiter for the search, e.g. '%' in s%regex%replacement%
+    int                    search_delim, // the delimiter for the search, e.g. '%' in
+                                 // s%regex%replacement%
     char_u         *pat,
     long           count,
     int                    options,
@@ -1476,11 +1477,11 @@ do_search(
                        msgbuf = trunc;
                    }
 
-    #ifdef FEAT_RIGHTLEFT
-                   // The search pattern could be shown on the right in rightleft
-                   // mode, but the 'ruler' and 'showcmd' area use it too, thus
-                   // it would be blanked out again very soon.  Show it on the
-                   // left, but do reverse the text.
+#ifdef FEAT_RIGHTLEFT
+                   // The search pattern could be shown on the right in
+                   // rightleft mode, but the 'ruler' and 'showcmd' area use
+                   // it too, thus it would be blanked out again very soon.
+                   // Show it on the left, but do reverse the text.
                    if (curwin->w_p_rl && *curwin->w_p_rlc == 's')
                    {
                        char_u *r;
@@ -1503,7 +1504,7 @@ do_search(
                                vim_memset(msgbuf + pat_len, ' ', r - msgbuf);
                        }
                    }
-    #endif
+#endif
                    msg_outtrans(msgbuf);
                    msg_clr_eos();
                    msg_check();
@@ -1548,6 +1549,9 @@ do_search(
            }
        }
 
+       /*
+        * The actual search.
+        */
        c = searchit(curwin, curbuf, &pos, NULL,
                                              dirc == '/' ? FORWARD : BACKWARD,
                searchstr, count, spats[0].off.end + (options &
@@ -1557,7 +1561,7 @@ do_search(
                RE_LAST, sia);
 
        if (dircp != NULL)
-           *dircp = search_delim;      // restore second '/' or '?' for normal_cmd()
+           *dircp = search_delim; // restore second '/' or '?' for normal_cmd()
 
        if (!shortmess(SHM_SEARCH)
                && ((dirc == '/' && LT_POS(pos, curwin->w_cursor))
@@ -4794,6 +4798,12 @@ do_fuzzymatch(typval_T *argvars, typval_T *rettv, int retmatchpos)
     int                ret;
     int                matchseq = FALSE;
 
+    if (in_vim9script()
+           && (check_for_list_arg(argvars, 0) == FAIL
+               || check_for_string_arg(argvars, 1) == FAIL
+               || check_for_opt_dict_arg(argvars, 2) == FAIL))
+       return;
+
     CLEAR_POINTER(&cb);
 
     // validate and get the arguments
index bd8cb6c6b2273a6cd786fd395f18dc5661725c6d..c208a0e56d992ece517c14e42752289833a70e8b 100644 (file)
@@ -2300,6 +2300,12 @@ f_sign_getplaced(typval_T *argvars, typval_T *rettv)
     if (rettv_list_alloc_id(rettv, aid_sign_getplaced) != OK)
        return;
 
+    if (in_vim9script()
+           && (check_for_opt_string_or_number_arg(argvars, 0) == FAIL
+               || (argvars[0].v_type != VAR_UNKNOWN
+                   && check_for_opt_dict_arg(argvars, 1) == FAIL)))
+       return;
+
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
        // get signs placed in the specified buffer
index 98d420c6aa878e472bf233bbfc4d4813d21f327c..bc0fc5e315d8843f4b641eaa2f8461f43c5cd833 100644 (file)
@@ -904,8 +904,7 @@ f_str2list(typval_T *argvars, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_bool_arg(argvars, 1) == FAIL)))
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
        return;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
@@ -1116,8 +1115,7 @@ f_strchars(typval_T *argvars, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_bool_arg(argvars, 1) == FAIL)))
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
        return;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
@@ -1141,8 +1139,7 @@ f_strdisplaywidth(typval_T *argvars, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_number_arg(argvars, 1) == FAIL)))
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
        return;
 
     s = tv_get_string(&argvars[0]);
@@ -1178,6 +1175,14 @@ f_strcharpart(typval_T *argvars, typval_T *rettv)
     int                slen;
     int                error = FALSE;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_opt_number_arg(argvars, 2) == FAIL
+               || (argvars[2].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 3) == FAIL)))
+       return;
+
     p = tv_get_string(&argvars[0]);
     slen = (int)STRLEN(p);
 
@@ -1261,6 +1266,14 @@ f_strpart(typval_T *argvars, typval_T *rettv)
     int                slen;
     int                error = FALSE;
 
+    if (in_vim9script()
+           && (check_for_string_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_opt_number_arg(argvars, 2) == FAIL
+               || (argvars[2].v_type != VAR_UNKNOWN
+                   && check_for_opt_bool_arg(argvars, 3) == FAIL)))
+       return;
+
     p = tv_get_string(&argvars[0]);
     slen = (int)STRLEN(p);
 
index 52645643b55a50100dcae8dce1c0c73219c13e36..c758e44742a4711bc044279cdf0246dcb865a890 100644 (file)
@@ -5928,11 +5928,17 @@ f_term_gettitle(typval_T *argvars, typval_T *rettv)
     void
 f_term_gettty(typval_T *argvars, typval_T *rettv)
 {
-    buf_T      *buf = term_get_buf(argvars, "term_gettty()");
+    buf_T      *buf;
     char_u     *p = NULL;
     int                num = 0;
 
+    if (in_vim9script()
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
+               || check_for_opt_bool_arg(argvars, 1) == FAIL))
+       return;
+
     rettv->v_type = VAR_STRING;
+    buf = term_get_buf(argvars, "term_gettty()");
     if (buf == NULL)
        return;
     if (argvars[1].v_type != VAR_UNKNOWN)
@@ -6098,9 +6104,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv UNUSED)
     term_T     *term;
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
                || check_for_string_arg(argvars, 1) == FAIL))
        return;
 
@@ -6175,9 +6179,16 @@ f_term_getansicolors(typval_T *argvars, typval_T *rettv)
     void
 f_term_setansicolors(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    buf_T      *buf = term_get_buf(argvars, "term_setansicolors()");
+    buf_T      *buf;
     term_T     *term;
 
+    if (in_vim9script()
+           && (check_for_opt_string_or_number_arg(argvars, 0) == FAIL
+               || (argvars[0].v_type != VAR_UNKNOWN
+                   && check_for_opt_list_arg(argvars, 1) == FAIL)))
+       return;
+
+    buf = term_get_buf(argvars, "term_setansicolors()");
     if (buf == NULL)
        return;
     term = buf->b_term;
@@ -6206,9 +6217,7 @@ f_term_setapi(typval_T *argvars, typval_T *rettv UNUSED)
     char_u     *api;
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
                || check_for_string_arg(argvars, 1) == FAIL))
        return;
 
@@ -6236,9 +6245,7 @@ f_term_setrestore(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     char_u     *cmd;
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
                || check_for_string_arg(argvars, 1) == FAIL))
        return;
 
@@ -6266,9 +6273,7 @@ f_term_setkill(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     char_u     *how;
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL)
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
                || check_for_string_arg(argvars, 1) == FAIL))
        return;
 
@@ -6321,11 +6326,8 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
     buf_T      *buf;
 
     if (in_vim9script()
-           && ((argvars[0].v_type != VAR_STRING
-                   && argvars[0].v_type != VAR_NUMBER
-                   && check_for_string_arg(argvars, 0) == FAIL) ||
-               (argvars[1].v_type != VAR_UNKNOWN
-                && check_for_number_arg(argvars, 1) == FAIL)))
+           && (check_for_string_or_number_arg(argvars, 0) == FAIL
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
        return;
 
     buf = term_get_buf(argvars, "term_wait()");
index 5eb3f3cb960ed119a2a26f6632e61ae9b8c33593..24ac7ea42ce867591066a943d35da705966aaad2 100644 (file)
@@ -423,24 +423,6 @@ func Test_blob_func_remove()
   END
   call CheckLegacyAndVim9Failure(lines, 'E979:')
 
-  let lines =<< trim END
-      VAR b = 0zDEADBEEF
-      call remove(1, 0)
-  END
-  call CheckLegacyAndVim9Failure(lines, 'E896:')
-
-  let lines =<< trim END
-      VAR b = 0zDEADBEEF
-      call remove(b, b)
-  END
-  call CheckLegacyAndVim9Failure(lines, 'E974:')
-
-  let lines =<< trim END
-      VAR b = 0zDEADBEEF
-      call remove(b, 1, [])
-  END
-  call CheckLegacyAndVim9Failure(lines, 'E745:')
-
   let lines =<< trim END
       VAR b = 0zDEADBEEF
       call remove(test_null_blob(), 1, 2)
@@ -504,16 +486,6 @@ func Test_blob_index()
       call assert_equal(-1, index(test_null_blob(), 1))
   END
   call CheckLegacyAndVim9Success(lines)
-
-  let lines =<< trim END
-      echo index(0z11110111, 0x11, [])
-  END
-  call CheckLegacyAndVim9Failure(lines, 'E745:')
-
-  let lines =<< trim END
-      call index("asdf", 0)
-  END
-  call CheckLegacyAndVim9Failure(lines, 'E897:')
 endfunc
 
 func Test_blob_insert()
index b727372a2694c2061bf5ad7440d120994eb0d687..237bfb4456be916effb544f78c3dc720dddbcdcb 100644 (file)
@@ -1093,11 +1093,11 @@ func Test_gui_mouse_event()
   let &guioptions = save_guioptions
 
   " Test invalid parameters for test_gui_mouse_event()
-  call assert_fails('call test_gui_mouse_event("", 1, 2, 3, 4)', 'E474:')
-  call assert_fails('call test_gui_mouse_event(0, "", 2, 3, 4)', 'E474:')
-  call assert_fails('call test_gui_mouse_event(0, 1, "", 3, 4)', 'E474:')
-  call assert_fails('call test_gui_mouse_event(0, 1, 2, "", 4)', 'E474:')
-  call assert_fails('call test_gui_mouse_event(0, 1, 2, 3, "")', 'E474:')
+  call assert_fails('call test_gui_mouse_event("", 1, 2, 3, 4)', 'E1210:')
+  call assert_fails('call test_gui_mouse_event(0, "", 2, 3, 4)', 'E1210:')
+  call assert_fails('call test_gui_mouse_event(0, 1, "", 3, 4)', 'E1210:')
+  call assert_fails('call test_gui_mouse_event(0, 1, 2, "", 4)', 'E1210:')
+  call assert_fails('call test_gui_mouse_event(0, 1, 2, 3, "")', 'E1210:')
 
   bw!
   call test_override('no_query_mouse', 0)
index e717163cc83110b0311147969bde64e79f151329..869915074dd191cc50bc6eb906e6829ec7fbec8f 100644 (file)
@@ -270,18 +270,10 @@ enddef
 def Test_browse()
   CheckFeature browse
 
-  var lines =<< trim END
-      browse(1, 2, 3, 4)
-  END
-  CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 2')
-  lines =<< trim END
-      browse(1, 'title', 3, 4)
-  END
-  CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 3')
-  lines =<< trim END
-      browse(1, 'title', 'dir', 4)
-  END
-  CheckDefExecAndScriptFailure(lines, 'E1174: String required for argument 4')
+  CheckDefAndScriptFailure2(['browse(2, "title", "dir", "file")'], 'E1013: Argument 1: type mismatch, expected bool but got number', 'E1212: Bool required for argument 1')
+  CheckDefAndScriptFailure2(['browse(true, 2, "dir", "file")'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['browse(true, "title", 3, "file")'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+  CheckDefAndScriptFailure2(['browse(true, "title", "dir", 4)'], 'E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4')
 enddef
 
 def Test_browsedir()
@@ -330,6 +322,8 @@ def Test_bufnr()
   buf = bufnr('Xdummy', true)
   buf->assert_notequal(-1)
   exe 'bwipe! ' .. buf
+  CheckDefAndScriptFailure2(['bufnr([1])'], 'E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['bufnr(1, 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
 enddef
 
 def Test_bufwinid()
@@ -379,22 +373,53 @@ enddef
 def Test_ch_canread()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefFailure(['ch_canread(10)'], 'E1013: Argument 1: type mismatch, expected channel but got number')
   endif
-  CheckDefFailure(['ch_canread(10)'], 'E1013: Argument 1: type mismatch, expected channel but got number')
 enddef
 
 def Test_ch_close()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefFailure(['ch_close("c")'], 'E1013: Argument 1: type mismatch, expected channel but got string')
   endif
-  CheckDefFailure(['ch_close("c")'], 'E1013: Argument 1: type mismatch, expected channel but got string')
 enddef
 
 def Test_ch_close_in()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefFailure(['ch_close_in(true)'], 'E1013: Argument 1: type mismatch, expected channel but got bool')
+  endif
+enddef
+
+def Test_ch_evalexpr()
+  if !has('channel')
+    CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_evalexpr(1, "a")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1218: Channel or Job required for argument 1')
+    CheckDefAndScriptFailure2(['ch_evalexpr(test_null_channel(), 1, [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
+  endif
+enddef
+
+def Test_ch_evalraw()
+  if !has('channel')
+    CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_evalraw(1, "")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1218: Channel or Job required for argument 1')
+    CheckDefAndScriptFailure2(['ch_evalraw(test_null_channel(), 1)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+    CheckDefAndScriptFailure2(['ch_evalraw(test_null_channel(), "", [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
+  endif
+enddef
+
+def Test_ch_getbufnr()
+  if !has('channel')
+    CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_getbufnr(1, "a")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1218: Channel or Job required for argument 1')
+    CheckDefAndScriptFailure2(['ch_getbufnr(test_null_channel(), 1)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
   endif
-  CheckDefFailure(['ch_close_in(true)'], 'E1013: Argument 1: type mismatch, expected channel but got bool')
 enddef
 
 def Test_ch_getjob()
@@ -410,67 +435,94 @@ enddef
 def Test_ch_info()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefFailure(['ch_info([1])'], 'E1013: Argument 1: type mismatch, expected channel but got list<number>')
   endif
-  CheckDefFailure(['ch_info([1])'], 'E1013: Argument 1: type mismatch, expected channel but got list<number>')
 enddef
 
 def Test_ch_logfile()
   if !has('channel')
     CheckFeature channel
-  endif
-  assert_fails('ch_logfile(true)', 'E1174:')
-  assert_fails('ch_logfile("foo", true)', 'E1174:')
+  else
+    assert_fails('ch_logfile(true)', 'E1174:')
+    assert_fails('ch_logfile("foo", true)', 'E1174:')
 
-  CheckDefAndScriptFailure2(['ch_logfile(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
-  CheckDefAndScriptFailure2(['ch_logfile("a", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2')
+    CheckDefAndScriptFailure2(['ch_logfile(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+    CheckDefAndScriptFailure2(['ch_logfile("a", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2')
+  endif
 enddef
 
 def Test_ch_open()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_open({"a": 10}, "a")'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1')
+    CheckDefAndScriptFailure2(['ch_open("a", [1])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2')
   endif
-  CheckDefAndScriptFailure2(['ch_open({"a": 10}, "a")'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1')
-  CheckDefAndScriptFailure2(['ch_open("a", [1])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2')
 enddef
 
 def Test_ch_read()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_read(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
+    CheckDefAndScriptFailure2(['ch_read(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
   endif
-  CheckDefAndScriptFailure2(['ch_read(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
-  CheckDefAndScriptFailure2(['ch_read(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
 enddef
 
 def Test_ch_readblob()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_readblob(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
+    CheckDefAndScriptFailure2(['ch_readblob(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
   endif
-  CheckDefAndScriptFailure2(['ch_readblob(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
-  CheckDefAndScriptFailure2(['ch_readblob(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
 enddef
 
 def Test_ch_readraw()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_readraw(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
+    CheckDefAndScriptFailure2(['ch_readraw(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
+  endif
+enddef
+
+def Test_ch_sendexpr()
+  if !has('channel')
+    CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_sendexpr(1, "a")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1218: Channel or Job required for argument 1')
+    CheckDefAndScriptFailure2(['ch_sendexpr(test_null_channel(), 1, [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
+  endif
+enddef
+
+def Test_ch_sendraw()
+  if !has('channel')
+    CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_sendraw(1, "")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1218: Channel or Job required for argument 1')
+    CheckDefAndScriptFailure2(['ch_sendraw(test_null_channel(), 1)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+    CheckDefAndScriptFailure2(['ch_sendraw(test_null_channel(), "", [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
   endif
-  CheckDefAndScriptFailure2(['ch_readraw(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
-  CheckDefAndScriptFailure2(['ch_readraw(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
 enddef
 
 def Test_ch_setoptions()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_setoptions(1, {})'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
+    CheckDefFailure(['ch_setoptions(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>')
   endif
-  CheckDefAndScriptFailure2(['ch_setoptions(1, {})'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
-  CheckDefFailure(['ch_setoptions(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>')
 enddef
 
 def Test_ch_status()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['ch_status(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
+    CheckDefAndScriptFailure2(['ch_status(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
   endif
-  CheckDefAndScriptFailure2(['ch_status(1)'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E475: Invalid argument')
-  CheckDefAndScriptFailure2(['ch_status(test_null_channel(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E715: Dictionary required')
 enddef
 
 def Test_char2nr()
@@ -538,6 +590,15 @@ def Test_col()
   bw!
 enddef
 
+def Test_complete()
+  CheckDefAndScriptFailure2(['complete("1", [])'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['complete(1, {})'], 'E1013: Argument 2: type mismatch, expected list<any> but got dict<unknown>', 'E1211: List required for argument 2')
+enddef
+
+def Test_complete_add()
+  CheckDefAndScriptFailure2(['complete_add([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
+enddef
+
 def Test_complete_info()
   CheckDefFailure(['complete_info("")'], 'E1013: Argument 1: type mismatch, expected list<string> but got string')
   CheckDefFailure(['complete_info({})'], 'E1013: Argument 1: type mismatch, expected list<string> but got dict<unknown>')
@@ -576,6 +637,12 @@ enddef
 def Test_count()
   count('ABC ABC ABC', 'b', true)->assert_equal(3)
   count('ABC ABC ABC', 'b', false)->assert_equal(0)
+  CheckDefAndScriptFailure2(['count(10, 1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['count("a", [1], 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
+  CheckDefAndScriptFailure2(['count("a", [1], 0, "b")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
+  count([1, 2, 2, 3], 2)->assert_equal(2)
+  count([1, 2, 2, 3], 2, false, 2)->assert_equal(1)
+  count({a: 1.1, b: 2.2, c: 1.1}, 1.1)->assert_equal(2)
 enddef
 
 def Test_cursor()
@@ -590,6 +657,9 @@ def Test_cursor()
     cursor('2', 1)
   END
   CheckDefExecAndScriptFailure(lines, 'E1209:')
+  CheckDefAndScriptFailure2(['cursor(0z10, 1)'], 'E1013: Argument 1: type mismatch, expected number but got blob', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['cursor(1, "2")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['cursor(1, 2, "3")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
 enddef
 
 def Test_debugbreak()
@@ -597,6 +667,10 @@ def Test_debugbreak()
   CheckDefFailure(['debugbreak("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
 enddef
 
+def Test_deepcopy()
+  CheckDefAndScriptFailure2(['deepcopy({}, 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
+enddef
+
 def Test_delete()
   var res: bool = delete('doesnotexist')
   assert_equal(true, res)
@@ -605,6 +679,12 @@ def Test_delete()
   CheckDefFailure(['delete("a", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number')
 enddef
 
+def Test_deletebufline()
+  CheckDefAndScriptFailure2(['deletebufline([], 2)'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['deletebufline("a", [])'], 'E1013: Argument 2: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['deletebufline("a", 2, 0z10)'], 'E1013: Argument 3: type mismatch, expected string but got blob', 'E1174: String required for argument 3')
+enddef
+
 def Test_diff_filler()
   CheckDefFailure(['diff_filler([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
   CheckDefFailure(['diff_filler(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool')
@@ -670,6 +750,9 @@ def Test_expand()
   split SomeFile
   expand('%', true, true)->assert_equal(['SomeFile'])
   close
+  CheckDefAndScriptFailure2(['expand(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['expand("a", 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
+  CheckDefAndScriptFailure2(['expand("a", true, 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
 enddef
 
 def Test_expandcmd()
@@ -858,6 +941,8 @@ def Test_flattennew()
       echo flatten([1, 2, 3])
   END
   CheckDefAndScriptFailure(lines, 'E1158:')
+  CheckDefAndScriptFailure2(['flattennew({})'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<unknown>', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['flattennew([], "1")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
 enddef
 
 " Test for float functions argument type
@@ -1033,6 +1118,9 @@ def Test_getbufline()
   getbufline(-1, 1, '$')->assert_equal([])
 
   bwipe!
+  CheckDefAndScriptFailure2(['getbufline([], 2)'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['getbufline("a", [])'], 'E1013: Argument 2: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['getbufline("a", 2, 0z10)'], 'E1013: Argument 3: type mismatch, expected string but got blob', 'E1174: String required for argument 3')
 enddef
 
 def Test_getchangelist()
@@ -1062,24 +1150,14 @@ def Test_getcharstr()
   CheckDefAndScriptFailure2(['getcharstr("1")'], 'E1013: Argument 1: type mismatch, expected bool but got string', 'E1135: Using a String as a Bool')
 enddef
 
-def Test_getenv()
-  if getenv('does-not_exist') == ''
-    assert_report('getenv() should return null')
-  endif
-  if getenv('does-not_exist') == null
-  else
-    assert_report('getenv() should return null')
-  endif
-  $SOMEENVVAR = 'some'
-  assert_equal('some', getenv('SOMEENVVAR'))
-  unlet $SOMEENVVAR
-enddef
-
 def Test_getcompletion()
   set wildignore=*.vim,*~
   var l = getcompletion('run', 'file', true)
   l->assert_equal([])
   set wildignore&
+  CheckDefAndScriptFailure2(['getcompletion(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['getcompletion("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['getcompletion("a", "b", 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
 enddef
 
 def Test_getcurpos()
@@ -1096,6 +1174,19 @@ def Test_getcwd()
   CheckDefFailure(['getcwd(1, "x")'], 'E1013: Argument 2: type mismatch, expected number but got string')
 enddef
 
+def Test_getenv()
+  if getenv('does-not_exist') == ''
+    assert_report('getenv() should return null')
+  endif
+  if getenv('does-not_exist') == null
+  else
+    assert_report('getenv() should return null')
+  endif
+  $SOMEENVVAR = 'some'
+  assert_equal('some', getenv('SOMEENVVAR'))
+  unlet $SOMEENVVAR
+enddef
+
 def Test_getfontname()
   CheckDefFailure(['getfontname(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
 enddef
@@ -1204,6 +1295,9 @@ def Test_getreg()
   setreg('a', lines)
   getreg('a', true, true)->assert_equal(lines)
   assert_fails('getreg("ab")', 'E1162:')
+  CheckDefAndScriptFailure2(['getreg(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['getreg(".", 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
+  CheckDefAndScriptFailure2(['getreg(".", 1, "b")'], 'E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3')
 enddef
 
 def Test_getreg_return_type()
@@ -1230,6 +1324,17 @@ def Test_gettabinfo()
   CheckDefFailure(['gettabinfo("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
 enddef
 
+def Test_gettabvar()
+  CheckDefAndScriptFailure2(['gettabvar("a", "b")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['gettabvar(1, 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+enddef
+
+def Test_gettabwinvar()
+  CheckDefAndScriptFailure2(['gettabwinvar("a", 2, "c")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['gettabwinvar(1, "b", "c", [])'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['gettabwinvar(1, 1, 3, {})'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+enddef
+
 def Test_gettagstack()
   CheckDefFailure(['gettagstack("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
 enddef
@@ -1247,8 +1352,17 @@ def Test_getwinpos()
   CheckDefFailure(['getwinpos("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
 enddef
 
+def Test_getwinvar()
+  CheckDefAndScriptFailure2(['getwinvar("a", "b")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['getwinvar(1, 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+enddef
+
 def Test_glob()
   glob('runtest.vim', true, true, true)->assert_equal(['runtest.vim'])
+  CheckDefAndScriptFailure2(['glob(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['glob("a", 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
+  CheckDefAndScriptFailure2(['glob("a", 1, "b")'], 'E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3')
+  CheckDefAndScriptFailure2(['glob("a", 1, true, 2)'], 'E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4')
 enddef
 
 def Test_glob2regpat()
@@ -1258,10 +1372,17 @@ enddef
 
 def Test_globpath()
   globpath('.', 'runtest.vim', true, true, true)->assert_equal(['./runtest.vim'])
+  CheckDefAndScriptFailure2(['globpath(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['globpath("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['globpath("a", "b", "c")'], 'E1013: Argument 3: type mismatch, expected bool but got string', 'E1212: Bool required for argument 3')
+  CheckDefAndScriptFailure2(['globpath("a", "b", true, "d")'], 'E1013: Argument 4: type mismatch, expected bool but got string', 'E1212: Bool required for argument 4')
+  CheckDefAndScriptFailure2(['globpath("a", "b", true, false, "e")'], 'E1013: Argument 5: type mismatch, expected bool but got string', 'E1212: Bool required for argument 5')
 enddef
 
 def Test_has()
   has('eval', true)->assert_equal(1)
+  CheckDefAndScriptFailure2(['has(["a"])'], 'E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['has("a", "b")'], 'E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2')
 enddef
 
 def Test_has_key()
@@ -1286,6 +1407,9 @@ def Test_hasmapto()
   iabbrev foo foobar
   hasmapto('foobar', 'i', true)->assert_equal(1)
   iunabbrev foo
+  CheckDefAndScriptFailure2(['hasmapto(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['hasmapto("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['hasmapto("a", "b", 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
 enddef
 
 def Test_histadd()
@@ -1330,6 +1454,9 @@ enddef
 
 def Test_index()
   index(['a', 'b', 'a', 'B'], 'b', 2, true)->assert_equal(3)
+  CheckDefAndScriptFailure2(['index("a", "a")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['index([1], 1.1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['index(0z1020, [1], 1, 2)'], 'E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4')
 enddef
 
 def Test_input()
@@ -1458,6 +1585,16 @@ def Test_job_info_return_type()
   endif
 enddef
 
+def Test_job_setoptions()
+  if !has('job')
+    CheckFeature job
+  else
+    CheckDefAndScriptFailure2(['job_setoptions(test_null_channel(), {})'], 'E1013: Argument 1: type mismatch, expected job but got channel', 'E1219: Job required for argument 1')
+    CheckDefAndScriptFailure2(['job_setoptions(test_null_job(), [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 2')
+    assert_equal('fail', job_status(test_null_job()))
+  endif
+enddef
+
 def Test_job_status()
   if !has('job')
     CheckFeature job
@@ -1467,6 +1604,20 @@ def Test_job_status()
   endif
 enddef
 
+def Test_job_stop()
+  if !has('job')
+    CheckFeature job
+  else
+    CheckDefAndScriptFailure2(['job_stop("a")'], 'E1013: Argument 1: type mismatch, expected job but got string', 'E1219: Job required for argument 1')
+    CheckDefAndScriptFailure2(['job_stop(test_null_job(), true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2')
+  endif
+enddef
+
+def Test_join()
+  CheckDefAndScriptFailure2(['join("abc")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['join([], 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+enddef
+
 def Test_js_decode()
   CheckDefFailure(['js_decode(10)'], 'E1013: Argument 1: type mismatch, expected string but got number')
   assert_equal([1, 2], js_decode('[1,2]'))
@@ -1512,6 +1663,11 @@ def Test_list2str_str2list_utf8()
   list2str(l, true)->assert_equal(s)
 enddef
 
+def Test_list2str()
+  CheckDefAndScriptFailure2(['list2str(".", true)'], 'E1013: Argument 1: type mismatch, expected list<number> but got string', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['list2str([1], 0z10)'], 'E1013: Argument 2: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 2')
+enddef
+
 def SID(): number
   return expand('<SID>')
           ->matchstr('<SNR>\zs\d\+\ze_$')
@@ -1526,6 +1682,27 @@ def Test_listener_remove()
   CheckDefAndScriptFailure2(['listener_remove("x")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1030: Using a String as a Number')
 enddef
 
+def Test_map_failure()
+  CheckFeature job
+
+  var lines =<< trim END
+      vim9script
+      writefile([], 'Xtmpfile')
+      silent e Xtmpfile
+      var d = {[bufnr('%')]: {a: 0}}
+      au BufReadPost * Func()
+      def Func()
+          if d->has_key('')
+          endif
+          eval d[expand('<abuf>')]->mapnew((_, v: dict<job>) => 0)
+      enddef
+      e
+  END
+  CheckScriptFailure(lines, 'E1013:')
+  au! BufReadPost
+  delete('Xtmpfile')
+enddef
+
 def Test_map_function_arg()
   var lines =<< trim END
       def MapOne(i: number, v: string): string
@@ -1591,12 +1768,10 @@ def Test_maparg()
         rhs: 'bar',
         buffer: 0})
   unmap foo
-enddef
-
-def Test_mapcheck()
-  iabbrev foo foobar
-  mapcheck('foo', 'i', true)->assert_equal('foobar')
-  iunabbrev foo
+  CheckDefAndScriptFailure2(['maparg(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['maparg("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['maparg("a", "b", 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
+  CheckDefAndScriptFailure2(['maparg("a", "b", true, 2)'], 'E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4')
 enddef
 
 def Test_maparg_mapset()
@@ -1607,25 +1782,19 @@ def Test_maparg_mapset()
   nunmap <F3>
 enddef
 
-def Test_map_failure()
-  CheckFeature job
+def Test_mapcheck()
+  iabbrev foo foobar
+  mapcheck('foo', 'i', true)->assert_equal('foobar')
+  iunabbrev foo
+  CheckDefAndScriptFailure2(['mapcheck(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['mapcheck("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['mapcheck("a", "b", 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
+enddef
 
-  var lines =<< trim END
-      vim9script
-      writefile([], 'Xtmpfile')
-      silent e Xtmpfile
-      var d = {[bufnr('%')]: {a: 0}}
-      au BufReadPost * Func()
-      def Func()
-          if d->has_key('')
-          endif
-          eval d[expand('<abuf>')]->mapnew((_, v: dict<job>) => 0)
-      enddef
-      e
-  END
-  CheckScriptFailure(lines, 'E1013:')
-  au! BufReadPost
-  delete('Xtmpfile')
+def Test_mapset()
+  CheckDefAndScriptFailure2(['mapset(1, true, {})'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['mapset("a", 2, {})'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
+  CheckDefAndScriptFailure2(['mapset("a", false, [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
 enddef
 
 def Test_match()
@@ -1668,6 +1837,18 @@ def Test_matchend()
   assert_equal(5, matchend(['a', 'b', 'c', 'b', 'd', 'b'], 'b', 2, 2))
 enddef
 
+def Test_matchfuzzy()
+  CheckDefAndScriptFailure2(['matchfuzzy({}, "p")'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<unknown>', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['matchfuzzy([], 1)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['matchfuzzy([], "a", [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
+enddef
+
+def Test_matchfuzzypos()
+  CheckDefAndScriptFailure2(['matchfuzzypos({}, "p")'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<unknown>', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['matchfuzzypos([], 1)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['matchfuzzypos([], "a", [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
+enddef
+
 def Test_matchlist()
   CheckDefAndScriptFailure2(['matchlist(0z12, "p")'], 'E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1')
   CheckDefAndScriptFailure2(['matchlist(["s"], [2])'], 'E1013: Argument 2: type mismatch, expected string but got list<number>', 'E1174: String required for argument 2')
@@ -1781,6 +1962,8 @@ enddef
 
 def Test_nr2char()
   nr2char(97, true)->assert_equal('a')
+  CheckDefAndScriptFailure2(['nr2char("x")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['nr2char(1, "a")'], 'E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2')
 enddef
 
 def Test_or()
@@ -1906,9 +2089,22 @@ enddef
 def Test_prompt_setprompt()
   if !has('channel')
     CheckFeature channel
+  else
+    CheckDefAndScriptFailure2(['prompt_setprompt([], "p")'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
+    CheckDefAndScriptFailure2(['prompt_setprompt(1, [])'], 'E1013: Argument 2: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 2')
   endif
-  CheckDefAndScriptFailure2(['prompt_setprompt([], "p")'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
-  CheckDefAndScriptFailure2(['prompt_setprompt(1, [])'], 'E1013: Argument 2: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 2')
+enddef
+
+def Test_prop_add()
+  CheckDefAndScriptFailure2(['prop_add("a", 2, {})'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['prop_add(1, "b", {})'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['prop_add(1, 2, [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
+enddef
+
+def Test_prop_clear()
+  CheckDefAndScriptFailure2(['prop_clear("a")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['prop_clear(1, "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['prop_clear(1, 2, [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
 enddef
 
 def Test_prop_find()
@@ -1922,6 +2118,12 @@ def Test_prop_list()
   CheckDefAndScriptFailure2(['prop_list(1, [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 2')
 enddef
 
+def Test_prop_remove()
+  CheckDefAndScriptFailure2(['prop_remove([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 1')
+  CheckDefAndScriptFailure2(['prop_remove({}, "a")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['prop_remove({}, 1, "b")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+enddef
+
 def Test_prop_type_add()
   CheckDefAndScriptFailure2(['prop_type_add({"a": 10}, "b")'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E731: Using a Dictionary as a String')
   CheckDefAndScriptFailure2(['prop_type_add("a", "b")'], 'E1013: Argument 2: type mismatch, expected dict<any> but got string', 'E715: Dictionary required')
@@ -2053,6 +2255,15 @@ def Test_reltimestr()
   assert_true(type(reltimestr(reltime())) == v:t_string)
 enddef
 
+def Test_remote_expr()
+  CheckFeature clientserver
+  CheckEnv DISPLAY
+  CheckDefAndScriptFailure2(['remote_expr(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['remote_expr("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['remote_expr("a", "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+  CheckDefAndScriptFailure2(['remote_expr("a", "b", "c", "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
+enddef
+
 def Test_remote_foreground()
   CheckFeature clientserver
   # remote_foreground() doesn't fail on MS-Windows
@@ -2077,6 +2288,14 @@ def Test_remote_read()
   CheckDefAndScriptFailure2(['remote_read("a", "x")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
 enddef
 
+def Test_remote_send()
+  CheckFeature clientserver
+  CheckEnv DISPLAY
+  CheckDefAndScriptFailure2(['remote_send(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['remote_send("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['remote_send("a", "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+enddef
+
 def Test_remote_startserver()
   CheckFeature clientserver
   CheckEnv DISPLAY
@@ -2089,6 +2308,31 @@ def Test_remove_const_list()
   assert_equal([3, 4], l)
 enddef
 
+def Test_remove()
+  CheckDefAndScriptFailure2(['remove("a", 1)'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E896: Argument of remove() must be a List, Dictionary or Blob')
+  CheckDefAndScriptFailure2(['remove([], "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['remove([], 1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['remove({}, 1.1)'], 'E1013: Argument 2: type mismatch, expected string but got float', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['remove(0z10, "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['remove(0z20, 1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  var l: any = [1, 2, 3, 4]
+  remove(l, 1)
+  assert_equal([1, 3, 4], l)
+  remove(l, 0, 1)
+  assert_equal([4], l)
+  var b: any = 0z1234.5678.90
+  remove(b, 1)
+  assert_equal(0z1256.7890, b)
+  remove(b, 1, 2)
+  assert_equal(0z1290, b)
+  var d: any = {a: 10, b: 20, c: 30}
+  remove(d, 'b')
+  assert_equal({a: 10, c: 30}, d)
+  var d2: any = {1: 'a', 2: 'b', 3: 'c'}
+  remove(d2, 2)
+  assert_equal({1: 'a', 3: 'c'}, d2)
+enddef
+
 def Test_remove_return_type()
   var l = remove({one: [1, 2], two: [3, 4]}, 'one')
   var res = 0
@@ -2202,6 +2446,13 @@ def Test_searchcount()
   CheckDefAndScriptFailure2(['searchcount([1])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<number>', 'E715: Dictionary required')
 enddef
 
+def Test_searchdecl()
+  searchdecl('blah', true, true)->assert_equal(1)
+  CheckDefAndScriptFailure2(['searchdecl(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['searchdecl("a", 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
+  CheckDefAndScriptFailure2(['searchdecl("a", true, 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
+enddef
+
 def Test_searchpair()
   new
   setline(1, "here { and } there")
@@ -2247,6 +2498,11 @@ def Test_server2client()
   CheckDefAndScriptFailure2(['server2client("a", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E573: Invalid server id used:')
 enddef
 
+def Test_shellescape()
+  CheckDefAndScriptFailure2(['shellescape(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['shellescape("a", 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
+enddef
+
 def Test_set_get_bufline()
   # similar to Test_setbufline_getbufline()
   var lines =<< trim END
@@ -2297,10 +2553,6 @@ def Test_set_get_bufline()
   CheckDefAndScriptSuccess(lines)
 enddef
 
-def Test_searchdecl()
-  searchdecl('blah', true, true)->assert_equal(1)
-enddef
-
 def Test_setbufvar()
   setbufvar(bufnr('%'), '&syntax', 'vim')
   &syntax->assert_equal('vim')
@@ -2326,23 +2578,6 @@ def Test_setbufvar()
   getbufvar('%', 'myvar')->assert_equal(123)
 enddef
 
-def Test_setcharsearch()
-  CheckDefFailure(['setcharsearch("x")'], 'E1013: Argument 1: type mismatch, expected dict<any> but got string')
-  CheckDefFailure(['setcharsearch([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
-  var d: dict<any> = {char: 'x', forward: 1, until: 1}
-  setcharsearch(d)
-  assert_equal(d, getcharsearch())
-enddef
-
-def Test_setcmdpos()
-  CheckDefFailure(['setcmdpos("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
-enddef
-
-def Test_setfperm()
-  CheckDefFailure(['setfperm(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number')
-  CheckDefFailure(['setfperm("a", 0z10)'], 'E1013: Argument 2: type mismatch, expected string but got blob')
-enddef
-
 def Test_setbufline()
   new
   var bnum = bufnr('%')
@@ -2364,6 +2599,35 @@ def Test_setcellwidths()
   CheckDefAndScriptFailure2(['setcellwidths({"a": 10})'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E714: List required')
 enddef
 
+def Test_setcharpos()
+  CheckDefAndScriptFailure2(['setcharpos(1, [])'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefFailure(['setcharpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
+  CheckDefAndScriptFailure2(['setcharpos(".", 1)'], 'E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2')
+enddef
+
+def Test_setcharsearch()
+  CheckDefFailure(['setcharsearch("x")'], 'E1013: Argument 1: type mismatch, expected dict<any> but got string')
+  CheckDefFailure(['setcharsearch([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
+  var d: dict<any> = {char: 'x', forward: 1, until: 1}
+  setcharsearch(d)
+  assert_equal(d, getcharsearch())
+enddef
+
+def Test_setcmdpos()
+  CheckDefFailure(['setcmdpos("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
+enddef
+
+def Test_setcursorcharpos()
+  CheckDefAndScriptFailure2(['setcursorcharpos(0z10, 1)'], 'E1013: Argument 1: type mismatch, expected number but got blob', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['setcursorcharpos(1, "2")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['setcursorcharpos(1, 2, "3")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+enddef
+
+def Test_setfperm()
+  CheckDefFailure(['setfperm(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number')
+  CheckDefFailure(['setfperm("a", 0z10)'], 'E1013: Argument 2: type mismatch, expected string but got blob')
+enddef
+
 def Test_setline()
   new
   setline(1, range(1, 4))
@@ -2383,6 +2647,27 @@ def Test_setloclist()
   var what = {items: items}
   setqflist([], ' ', what)
   setloclist(0, [], ' ', what)
+  CheckDefAndScriptFailure2(['setloclist("1", [])'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['setloclist(1, 2)'], 'E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2')
+  CheckDefAndScriptFailure2(['setloclist(1, [], 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+  CheckDefAndScriptFailure2(['setloclist(1, [], "a", [])'], 'E1013: Argument 4: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 4')
+enddef
+
+def Test_setmatches()
+  CheckDefAndScriptFailure2(['setmatches({})'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<unknown>', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['setmatches([], "1")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+enddef
+
+def Test_setpos()
+  CheckDefAndScriptFailure2(['setpos(1, [])'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefFailure(['setpos(".", ["a"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
+  CheckDefAndScriptFailure2(['setpos(".", 1)'], 'E1013: Argument 2: type mismatch, expected list<number> but got number', 'E1211: List required for argument 2')
+enddef
+
+def Test_setqflist()
+  CheckDefAndScriptFailure2(['setqflist(1, "")'], 'E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['setqflist([], 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['setqflist([], "", [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
 enddef
 
 def Test_setreg()
@@ -2393,6 +2678,28 @@ def Test_setreg()
   assert_fails('setreg("ab", 0)', 'E1162:')
 enddef 
 
+def Test_settabvar()
+  CheckDefAndScriptFailure2(['settabvar("a", "b", 1)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['settabvar(1, 2, "c")'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+enddef
+
+def Test_settabwinvar()
+  CheckDefAndScriptFailure2(['settabwinvar("a", 2, "c", true)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['settabwinvar(1, "b", "c", [])'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['settabwinvar(1, 1, 3, {})'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+enddef
+
+def Test_settagstack()
+  CheckDefAndScriptFailure2(['settagstack(true, {})'], 'E1013: Argument 1: type mismatch, expected number but got bool', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['settagstack(1, [1])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 2')
+  CheckDefAndScriptFailure2(['settagstack(1, {}, 2)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+enddef
+
+def Test_setwinvar()
+  CheckDefAndScriptFailure2(['setwinvar("a", "b", 1)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['setwinvar(1, 2, "c")'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+enddef
+
 def Test_sha256()
   CheckDefFailure(['sha256(100)'], 'E1013: Argument 1: type mismatch, expected string but got number')
   CheckDefFailure(['sha256(0zABCD)'], 'E1013: Argument 1: type mismatch, expected string but got blob')
@@ -2414,6 +2721,12 @@ def Test_sign_getdefined()
   CheckDefAndScriptFailure2(['sign_getdefined(2)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
 enddef
 
+def Test_sign_getplaced()
+  CheckDefAndScriptFailure2(['sign_getplaced(["x"])'], 'E1013: Argument 1: type mismatch, expected string but got list<string>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['sign_getplaced(1, ["a"])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2')
+  CheckDefAndScriptFailure2(['sign_getplaced("a", 1.1)'], 'E1013: Argument 2: type mismatch, expected dict<any> but got float', 'E1206: Dictionary required for argument 2')
+enddef
+
 def Test_sign_placelist()
   CheckDefAndScriptFailure2(['sign_placelist("x")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E714: List required')
   CheckDefAndScriptFailure2(['sign_placelist({"a": 10})'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E714: List required')
@@ -2461,6 +2774,9 @@ def Test_slice()
   assert_equal(0z11, slice(0z001122334455, 1, -4))
   assert_equal(0z, slice(0z001122334455, 1, -5))
   assert_equal(0z, slice(0z001122334455, 1, -6))
+  CheckDefAndScriptFailure2(['slice({"a": 10}, 1)'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['slice([1, 2, 3], "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['slice("abc", 1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
 enddef
 
 def Test_spellsuggest()
@@ -2469,6 +2785,9 @@ def Test_spellsuggest()
   else
     spellsuggest('marrch', 1, true)->assert_equal(['March'])
   endif
+  CheckDefAndScriptFailure2(['spellsuggest(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['spellsuggest("a", "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['spellsuggest("a", 1, 0z01)'], 'E1013: Argument 3: type mismatch, expected bool but got blob', 'E1212: Bool required for argument 3')
 enddef
 
 def Test_sound_stop()
@@ -2508,6 +2827,9 @@ enddef
 
 def Test_split()
   split('  aa  bb  ', '\W\+', true)->assert_equal(['', 'aa', 'bb', ''])
+  CheckDefAndScriptFailure2(['split(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['split("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['split("a", "b", 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
 enddef
 
 def Test_srand()
@@ -2557,6 +2879,13 @@ def Test_strcharlen()
   strcharlen(99)->assert_equal(2)
 enddef
 
+def Test_strcharpart()
+  CheckDefAndScriptFailure2(['strcharpart(1, 2)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['strcharpart("a", "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['strcharpart("a", 1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['strcharpart("a", 1, 1, 2)'], 'E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4')
+enddef
+
 def Test_strchars()
   strchars("A\u20dd", true)->assert_equal(1)
   CheckDefAndScriptFailure2(['strchars(10)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
@@ -2593,6 +2922,13 @@ def Test_strlen()
   strlen(99)->assert_equal(2)
 enddef
 
+def Test_strpart()
+  CheckDefAndScriptFailure2(['strpart(1, 2)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['strpart("a", "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['strpart("a", 1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['strpart("a", 1, 1, 2)'], 'E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4')
+enddef
+
 def Test_strptime()
   CheckFunction strptime
   CheckDefFailure(['strptime(10, "2021")'], 'E1013: Argument 1: type mismatch, expected string but got number')
@@ -2626,6 +2962,8 @@ def Test_submatch()
   var actual = substitute('A123456789', pat, Rep, '')
   var expected = "[['A123456789'], ['1'], ['2'], ['3'], ['4'], ['5'], ['6'], ['7'], ['8'], ['9']]"
   actual->assert_equal(expected)
+  CheckDefAndScriptFailure2(['submatch("x")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['submatch(1, "a")'], 'E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2')
 enddef
 
 def Test_substitute()
@@ -2653,6 +2991,9 @@ def Test_synID()
   setline(1, "text")
   synID(1, 1, true)->assert_equal(0)
   bwipe!
+  CheckDefAndScriptFailure2(['synID(0z10, 1, true)'], 'E1013: Argument 1: type mismatch, expected string but got blob', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['synID("a", true, false)'], 'E1013: Argument 2: type mismatch, expected number but got bool', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['synID(1, 1, 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
 enddef
 
 def Test_synIDtrans()
@@ -2753,6 +3094,8 @@ def Test_term_gettty()
     term_gettty(buf, true)->assert_notequal('')
     StopShellInTerminal(buf)
   endif
+  CheckDefAndScriptFailure2(['term_gettty([1])'], 'E1013: Argument 1: type mismatch, expected string but got list<number>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['term_gettty(1, 2)'], 'E1013: Argument 2: type mismatch, expected bool but got number', 'E1212: Bool required for argument 2')
 enddef
 
 def Test_term_sendkeys()
@@ -2761,6 +3104,12 @@ def Test_term_sendkeys()
   CheckDefAndScriptFailure2(['term_sendkeys(1, [])'], 'E1013: Argument 2: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 2')
 enddef
 
+def Test_term_setansicolors()
+  CheckRunVimInTerminal
+  CheckDefAndScriptFailure2(['term_setansicolors([], "p")'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['term_setansicolors(10, {})'], 'E1013: Argument 2: type mismatch, expected list<any> but got dict<unknown>', 'E1211: List required for argument 2')
+enddef
+
 def Test_term_setapi()
   CheckRunVimInTerminal
   CheckDefAndScriptFailure2(['term_setapi([], "p")'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E1174: String required for argument 1')
@@ -2811,6 +3160,15 @@ def Test_test_getvalue()
   CheckDefAndScriptFailure2(['test_getvalue(1.1)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E474: Invalid argument')
 enddef
 
+def Test_test_gui_mouse_event()
+  CheckGui
+  CheckDefAndScriptFailure2(['test_gui_mouse_event(1.1, 1, 1, 1, 1)'], 'E1013: Argument 1: type mismatch, expected number but got float', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['test_gui_mouse_event(1, "1", 1, 1, 1)'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['test_gui_mouse_event(1, 1, "1", 1, 1)'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['test_gui_mouse_event(1, 1, 1, "1", 1)'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
+  CheckDefAndScriptFailure2(['test_gui_mouse_event(1, 1, 1, 1, "1")'], 'E1013: Argument 5: type mismatch, expected number but got string', 'E1210: Number required for argument 5')
+enddef
+
 def Test_test_ignore_error()
   CheckDefAndScriptFailure2(['test_ignore_error([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>', 'E474: Invalid argument')
   test_ignore_error('RESET')
@@ -2845,6 +3203,11 @@ def Test_timer_info()
   assert_equal([], timer_info())
 enddef
 
+def Test_timer_pause()
+  CheckDefAndScriptFailure2(['timer_pause("x", 1)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['timer_pause(1, "a")'], 'E1013: Argument 2: type mismatch, expected bool but got string', 'E1212: Bool required for argument 2')
+enddef
+
 def Test_timer_paused()
   var id = timer_start(50, () => 0)
   timer_pause(id, true)
@@ -2955,6 +3318,9 @@ def Test_win_splitmove()
   split
   win_splitmove(1, 2, {vertical: true, rightbelow: true})
   close
+  CheckDefAndScriptFailure2(['win_splitmove("a", 2)'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['win_splitmove(1, "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['win_splitmove(1, 2, [])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 3')
 enddef
 
 def Test_winbufnr()
index 42030d726da87663ceb70dfde5cc6a5a376a4b6f..5b2f7af138769986d2e3e526feb927ff0879eca5 100644 (file)
@@ -1246,15 +1246,12 @@ f_test_gui_mouse_event(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     int                repeated_click;
     int_u      mods;
 
-    if (argvars[0].v_type != VAR_NUMBER
-           || (argvars[1].v_type) != VAR_NUMBER
-           || (argvars[2].v_type) != VAR_NUMBER
-           || (argvars[3].v_type) != VAR_NUMBER
-           || (argvars[4].v_type) != VAR_NUMBER)
-    {
-       emsg(_(e_invarg));
+    if (check_for_number_arg(argvars, 0) == FAIL
+           || check_for_number_arg(argvars, 1) == FAIL
+           || check_for_number_arg(argvars, 2) == FAIL
+           || check_for_number_arg(argvars, 3) == FAIL
+           || check_for_number_arg(argvars, 4) == FAIL)
        return;
-    }
 
     button = tv_get_number(&argvars[0]);
     row = tv_get_number(&argvars[1]);
index c2000a3c3e0b7391697900f29d9888c6f2926c8b..fdbb14df874d8fc043d5669826565a9b3bd811ba 100644 (file)
@@ -158,6 +158,12 @@ f_prop_add(typval_T *argvars, typval_T *rettv UNUSED)
     linenr_T   start_lnum;
     colnr_T    start_col;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_number_arg(argvars, 1) == FAIL
+               || check_for_dict_arg(argvars, 2) == FAIL))
+       return;
+
     start_lnum = tv_get_number(&argvars[0]);
     start_col = tv_get_number(&argvars[1]);
     if (start_col < 1)
@@ -532,12 +538,21 @@ text_prop_type_by_id(buf_T *buf, int id)
     void
 f_prop_clear(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    linenr_T start = tv_get_number(&argvars[0]);
-    linenr_T end = start;
+    linenr_T start;
+    linenr_T end;
     linenr_T lnum;
     buf_T    *buf = curbuf;
     int            did_clear = FALSE;
 
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_opt_number_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_dict_arg(argvars, 2) == FAIL)))
+       return;
+
+    start = tv_get_number(&argvars[0]);
+    end = start;
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
        end = tv_get_number(&argvars[1]);
@@ -774,8 +789,7 @@ f_prop_list(typval_T *argvars, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_number_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN &&
-                   check_for_dict_arg(argvars, 1) == FAIL)))
+               || check_for_opt_dict_arg(argvars, 1) == FAIL))
        return;
 
     lnum = tv_get_number(&argvars[0]);
@@ -832,6 +846,14 @@ f_prop_remove(typval_T *argvars, typval_T *rettv)
     int                both;
 
     rettv->vval.v_number = 0;
+
+    if (in_vim9script()
+           && (check_for_dict_arg(argvars, 0) == FAIL
+               || check_for_opt_number_arg(argvars, 1) == FAIL
+               || (argvars[1].v_type != VAR_UNKNOWN
+                   && check_for_opt_number_arg(argvars, 2) == FAIL)))
+       return;
+
     if (argvars[0].v_type != VAR_DICT || argvars[0].vval.v_dict == NULL)
     {
        emsg(_(e_invarg));
index 796fc58c96ff3d03c08f1f48fff1cc141d3c8170..eeefeb6a8e4eeec0c0e1f4cdb870b9732043c0a1 100644 (file)
@@ -270,8 +270,7 @@ f_strftime(typval_T *argvars, typval_T *rettv)
 
     if (in_vim9script()
            && (check_for_string_arg(argvars, 0) == FAIL
-               || (argvars[1].v_type != VAR_UNKNOWN
-                   && check_for_number_arg(argvars, 1) == FAIL)))
+               || check_for_opt_number_arg(argvars, 1) == FAIL))
        return;
 
     rettv->v_type = VAR_STRING;
@@ -777,12 +776,17 @@ f_timer_info(typval_T *argvars, typval_T *rettv)
 f_timer_pause(typval_T *argvars, typval_T *rettv UNUSED)
 {
     timer_T    *timer = NULL;
-    int                paused = (int)tv_get_bool(&argvars[1]);
+
+    if (in_vim9script()
+           && (check_for_number_arg(argvars, 0) == FAIL
+               || check_for_bool_arg(argvars, 1) == FAIL))
+       return;
 
     if (argvars[0].v_type != VAR_NUMBER)
        emsg(_(e_number_exp));
     else
     {
+       int     paused = (int)tv_get_bool(&argvars[1]);
        timer = find_timer((int)tv_get_number(&argvars[0]));
        if (timer != NULL)
            timer->tr_paused = paused;
index 9d5903f649063c8cad559fc43751e4a0e79b62f7..29c925d66e32f3122f881ca8b2c21c2fda8c8488 100644 (file)
@@ -384,6 +384,16 @@ check_for_nonempty_string_arg(typval_T *args, int idx)
     return OK;
 }
 
+/*
+ * Check for an optional string argument at 'idx'
+ */
+    int
+check_for_opt_string_arg(typval_T *args, int idx)
+{
+    return (args[idx].v_type == VAR_UNKNOWN
+           || check_for_string_arg(args, idx) != FAIL);
+}
+
 /*
  * Give an error and return FAIL unless "args[idx]" is a number.
  */
@@ -401,6 +411,16 @@ check_for_number_arg(typval_T *args, int idx)
     return OK;
 }
 
+/*
+ * Check for an optional number argument at 'idx'
+ */
+    int
+check_for_opt_number_arg(typval_T *args, int idx)
+{
+    return (args[idx].v_type == VAR_UNKNOWN
+           || check_for_number_arg(args, idx) != FAIL);
+}
+
 /*
  * Give an error and return FAIL unless "args[idx]" is a bool.
  */
@@ -421,6 +441,16 @@ check_for_bool_arg(typval_T *args, int idx)
     return OK;
 }
 
+/*
+ * Check for an optional bool argument at 'idx'
+ */
+    int
+check_for_opt_bool_arg(typval_T *args, int idx)
+{
+    return (args[idx].v_type == VAR_UNKNOWN
+           || check_for_bool_arg(args, idx) != FAIL);
+}
+
 /*
  * Give an error and return FAIL unless "args[idx]" is a list.
  */
@@ -438,6 +468,16 @@ check_for_list_arg(typval_T *args, int idx)
     return OK;
 }
 
+/*
+ * Check for an optional list argument at 'idx'
+ */
+    int
+check_for_opt_list_arg(typval_T *args, int idx)
+{
+    return (args[idx].v_type == VAR_UNKNOWN
+           || check_for_list_arg(args, idx) != FAIL);
+}
+
 /*
  * Give an error and return FAIL unless "args[idx]" is a dict.
  */
@@ -455,6 +495,169 @@ check_for_dict_arg(typval_T *args, int idx)
     return OK;
 }
 
+/*
+ * Check for an optional dict argument at 'idx'
+ */
+    int
+check_for_opt_dict_arg(typval_T *args, int idx)
+{
+    return (args[idx].v_type == VAR_UNKNOWN
+           || check_for_dict_arg(args, idx) != FAIL);
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a blob.
+ */
+    int
+check_for_blob_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_BLOB)
+    {
+       if (idx >= 0)
+           semsg(_(e_blob_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_blobreq));
+       return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a channel or a job.
+ */
+    int
+check_for_chan_or_job_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_CHANNEL && args[idx].v_type != VAR_JOB)
+    {
+       if (idx >= 0)
+           semsg(_(e_chan_or_job_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_chan_or_job_req));
+       return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a job.
+ */
+    int
+check_for_job_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_JOB)
+    {
+       if (idx >= 0)
+           semsg(_(e_job_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_jobreq));
+       return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a string or
+ * a number.
+ */
+    int
+check_for_string_or_number_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
+    {
+       if (idx >= 0)
+           semsg(_(e_string_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_stringreq));
+       return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a string or
+ * a number (buffer)
+ */
+    int
+check_for_buffer_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
+    {
+       if (idx >= 0)
+           semsg(_(e_string_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_stringreq));
+       return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a string or
+ * a number (line)
+ */
+    int
+check_for_lnum_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_NUMBER)
+    {
+       if (idx >= 0)
+           semsg(_(e_string_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_stringreq));
+       return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a string or
+ * a number (line)
+ */
+    int
+check_for_opt_lnum_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_UNKNOWN
+           && args[idx].v_type != VAR_STRING
+           && args[idx].v_type != VAR_NUMBER)
+    {
+       if (idx >= 0)
+           semsg(_(e_string_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_stringreq));
+       return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Check for an optional string or number argument at 'idx'
+ */
+    int
+check_for_opt_string_or_number_arg(typval_T *args, int idx)
+{
+    return (args[idx].v_type == VAR_UNKNOWN
+           || check_for_string_or_number_arg(args, idx) != FAIL);
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a string or
+ * a blob.
+ */
+    int
+check_for_string_or_blob_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_STRING && args[idx].v_type != VAR_BLOB)
+    {
+       if (idx >= 0)
+           semsg(_(e_string_required_for_argument_nr), idx + 1);
+       else
+           emsg(_(e_stringreq));
+       return FAIL;
+    }
+    return OK;
+}
+
 /*
  * Get the string value of a variable.
  * If it is a Number variable, the number is converted into a string.
index 64997fd9ed210990e0d88601777c87427dd7a34b..4244d82cacadf962fdbaba50c1e9bbc92864e0ef 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3188,
 /**/
     3187,
 /**/