changeset 25338:e2be9f3c5907 v8.2.3206

patch 8.2.3206: Vim9: argument types are not checked at compile time Commit: https://github.com/vim/vim/commit/0ad871dc4dfe1026e14931a55c225616b63f4c5b Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Fri Jul 23 20:37:56 2021 +0200 patch 8.2.3206: Vim9: argument types are not checked at compile time Problem: Vim9: argument types are not checked at compile time. Solution: Add several more type checks. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/8611)
author Bram Moolenaar <Bram@vim.org>
date Fri, 23 Jul 2021 20:45:05 +0200
parents 0e5cb14de298
children 5f0765ae6ad9
files src/blob.c src/cmdhist.c src/dict.c src/errors.h src/evalfunc.c src/filepath.c src/globals.h src/job.c src/list.c src/match.c src/misc1.c src/popupwin.c src/proto/typval.pro src/sign.c src/terminal.c src/testdir/test_blob.vim src/testdir/test_vim9_builtin.vim src/typval.c src/version.c
diffstat 19 files changed, 457 insertions(+), 153 deletions(-) [+]
line wrap: on
line diff
--- a/src/blob.c
+++ b/src/blob.c
@@ -418,12 +418,6 @@ blob_remove(typval_T *argvars, typval_T 
     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)
     {
--- a/src/cmdhist.c
+++ b/src/cmdhist.c
@@ -570,6 +570,11 @@ f_histdel(typval_T *argvars UNUSED, typv
     char_u	buf[NUMBUFLEN];
     char_u	*str;
 
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_opt_string_or_number_arg(argvars, 1) == FAIL))
+	return;
+
     str = tv_get_string_chk(&argvars[0]);	// NULL on type error
     if (str == NULL)
 	n = 0;
--- a/src/dict.c
+++ b/src/dict.c
@@ -1340,11 +1340,6 @@ dict_remove(typval_T *argvars, typval_T 
     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
--- a/src/errors.h
+++ b/src/errors.h
@@ -613,9 +613,7 @@ EXTERN char e_digraph_argument_must_be_o
 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"));
+	INIT(= N_("E1217: Channel or Job required for argument %d"));
 EXTERN char e_job_required_for_argument_nr[]
-	INIT(= N_("E1219: Job required for argument %d"));
+	INIT(= N_("E1218: Job required for argument %d"));
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -572,12 +572,29 @@ arg_remove2(type_T *type, argcontext_T *
 }
 
 /*
+ * Check "type" which is the first argument of repeat().
+ */
+    static int
+arg_repeat1(type_T *type, argcontext_T *context)
+{
+    if (type->tt_type == VAR_ANY
+	    || type->tt_type == VAR_STRING
+	    || type->tt_type == VAR_NUMBER
+	    || type->tt_type == VAR_LIST)
+	return OK;
+
+    arg_type_mismatch(&t_string, type, context->arg_idx + 1);
+    return FAIL;
+}
+
+/*
  * 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
+    if (type->tt_type == VAR_ANY
+	    || type->tt_type == VAR_LIST
 	    || type->tt_type == VAR_BLOB
 	    || type->tt_type == VAR_STRING)
 	return OK;
@@ -592,7 +609,8 @@ arg_slice1(type_T *type, argcontext_T *c
     static int
 arg_count1(type_T *type, argcontext_T *context)
 {
-    if (type->tt_type == VAR_STRING
+    if (type->tt_type == VAR_ANY
+	    || type->tt_type == VAR_STRING
 	    || type->tt_type == VAR_LIST
 	    || type->tt_type == VAR_DICT)
 	return OK;
@@ -607,7 +625,8 @@ arg_count1(type_T *type, argcontext_T *c
     static int
 arg_cursor1(type_T *type, argcontext_T *context)
 {
-    if (type->tt_type == VAR_NUMBER
+    if (type->tt_type == VAR_ANY
+	    || type->tt_type == VAR_NUMBER
 	    || type->tt_type == VAR_STRING
 	    || type->tt_type == VAR_LIST)
 	return OK;
@@ -642,28 +661,30 @@ static argcheck_T arg2_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_string_dict[] = {arg_string, arg_dict_any};
+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_string_or_list_dict[] = {arg_string_or_list_any, arg_dict_any};
+static argcheck_T arg2_string_string_or_number[] = {arg_string, arg_string_or_nr};
 static argcheck_T arg2_list_number[] = {arg_list_number, arg_list_number};
-static argcheck_T arg2_lnum[] = {arg_lnum, arg_lnum};
+static argcheck_T arg2_list_number_bool[] = {arg_list_number, arg_bool};
 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_number_string[] = {arg_number, arg_string};
 static argcheck_T arg2_number_bool[] = {arg_number, arg_bool};
 static argcheck_T arg2_number_list[] = {arg_number, arg_list_any};
+static argcheck_T arg2_number_dict_any[] = {arg_number, arg_dict_any};
+static argcheck_T arg2_number_string_or_list[] = {arg_number, arg_string_or_list_any};
 static argcheck_T arg2_dict_string[] = {arg_dict_any, arg_string};
 static argcheck_T arg2_dict_any_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_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_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_lnum[] = {arg_lnum, arg_lnum};
 static argcheck_T arg2_lnum_number[] = {arg_lnum, arg_number};
 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_number_dict_any[] = {arg_number, arg_dict_any};
 static argcheck_T arg2_buffer_string[] = {arg_buffer, arg_string};
 static argcheck_T arg2_buffer_number[] = {arg_buffer, arg_number};
 static argcheck_T arg2_buffer_bool[] = {arg_buffer, arg_bool};
@@ -673,8 +694,10 @@ static argcheck_T arg3_string[] = {arg_s
 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_number_string_buffer[] = {arg_number, arg_string, arg_buffer};
 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_dict[] = {arg_string, arg_string, arg_dict_any};
 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};
@@ -683,35 +706,46 @@ static argcheck_T arg3_dict_number_numbe
 static argcheck_T arg3_lnum_number_bool[] = {arg_lnum, arg_number, arg_bool};
 static argcheck_T arg3_buffer_lnum_lnum[] = {arg_buffer, arg_lnum, arg_lnum};
 static argcheck_T arg3_buffer_number_number[] = {arg_buffer, arg_number, arg_number};
+static argcheck_T arg3_buffer_string_dict[] = {arg_buffer, arg_string, arg_dict_any};
 static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL};
+static argcheck_T arg4_string_string_number_string[] = {arg_string, arg_string, arg_number, arg_string};
 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_chanexpr[] = {arg_chan_or_job, NULL, arg_dict_any};
+static argcheck_T arg23_chanraw[] = {arg_chan_or_job, arg_string_or_blob, arg_dict_any};
+static argcheck_T arg24_count[] = {arg_count1, NULL, arg_bool, arg_number};
+static argcheck_T arg13_cursor[] = {arg_cursor1, arg_number, arg_number};
+static argcheck_T arg12_deepcopy[] = {NULL, arg_bool};
+static argcheck_T arg12_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 arg14_glob[] = {arg_string, arg_bool, arg_bool, arg_bool};
+static argcheck_T arg25_globpath[] = {arg_string, arg_string, arg_bool, arg_bool, arg_bool};
+static argcheck_T arg24_index[] = {arg_list_or_blob, arg_item_of_prev, arg_number, arg_bool};
+static argcheck_T arg23_insert[] = {arg_list_or_blob, arg_item_of_prev, arg_number};
+static argcheck_T arg2_mapfilter[] = {arg_list_or_dict_or_blob, NULL};
+static argcheck_T arg14_maparg[] = {arg_string, arg_string, arg_bool, arg_bool};
+static argcheck_T arg25_matchadd[] = {arg_string, arg_string, arg_number, arg_number, arg_dict_any};
+static argcheck_T arg25_matchaddpos[] = {arg_string, arg_list_number, arg_number, arg_number, arg_dict_any};
+static argcheck_T arg23_reduce[] = {arg_list_or_blob, NULL, NULL};
+static argcheck_T arg24_remote_expr[] = {arg_string, arg_string, arg_string, arg_number};
+static argcheck_T arg23_remove[] = {arg_list_or_dict_or_blob, arg_remove2, arg_number};
+static argcheck_T arg2_repeat[] = {arg_repeat1, arg_number};
+static argcheck_T arg15_search[] = {arg_string, arg_string, arg_number, arg_number, NULL};
 static argcheck_T arg3_setbufline[] = {arg_buffer, arg_lnum, arg_str_or_nr_or_list};
 static argcheck_T arg2_setline[] = {arg_lnum, 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_buffer, 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 arg24_setloclist[] = {arg_number, arg_list_any, arg_string, arg_dict_any};
+static argcheck_T arg13_setqflist[] = {arg_list_any, arg_string, arg_dict_any};
+static argcheck_T arg23_settagstack[] = {arg_number, arg_dict_any, arg_string};
+static argcheck_T arg02_sign_getplaced[] = {arg_buffer, arg_dict_any};
+static argcheck_T arg45_sign_place[] = {arg_number, arg_string, arg_string, arg_buffer, arg_dict_any};
+static argcheck_T arg23_slice[] = {arg_slice1, arg_number, arg_number};
+static argcheck_T arg13_sortuniq[] = {arg_list_any, NULL, arg_dict_any};
+static argcheck_T arg24_strpart[] = {arg_string, arg_number, arg_number, arg_bool};
+static argcheck_T arg12_system[] = {arg_string, arg_str_or_nr_or_list};
 static argcheck_T arg23_win_execute[] = {arg_number, arg_string_or_list_string, arg_string};
+static argcheck_T arg23_writefile[] = {arg_list_or_blob, arg_string, arg_string};
 static argcheck_T arg4_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number};
-static argcheck_T arg15_search[] = {arg_string, arg_string, arg_number, arg_number, NULL};
 
 
 /*
@@ -986,7 +1020,7 @@ static funcentry_T global_functions[] =
 			ret_any,	    FLOAT_FUNC(f_abs)},
     {"acos",		1, 1, FEARG_1,	    arg1_float_or_nr,
 			ret_float,	    FLOAT_FUNC(f_acos)},
-    {"add",		2, 2, FEARG_1,	    NULL /* arg2_listblob_item */,
+    {"add",		2, 2, FEARG_1,	    arg2_listblob_item,
 			ret_first_arg,	    f_add},
     {"and",		2, 2, FEARG_1,	    arg2_number,
 			ret_number,	    f_and},
@@ -1102,9 +1136,9 @@ 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,	    arg3_chanexpr,
+    {"ch_evalexpr",	2, 3, FEARG_1,	    arg23_chanexpr,
 			ret_any,	    JOB_FUNC(f_ch_evalexpr)},
-    {"ch_evalraw",	2, 3, FEARG_1,	    arg3_chanraw,
+    {"ch_evalraw",	2, 3, FEARG_1,	    arg23_chanraw,
 			ret_any,	    JOB_FUNC(f_ch_evalraw)},
     {"ch_getbufnr",	2, 2, FEARG_1,	    arg2_chan_or_job_string,
 			ret_number,	    JOB_FUNC(f_ch_getbufnr)},
@@ -1124,9 +1158,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,	    arg3_chanexpr,
+    {"ch_sendexpr",	2, 3, FEARG_1,	    arg23_chanexpr,
 			ret_void,	    JOB_FUNC(f_ch_sendexpr)},
-    {"ch_sendraw",	2, 3, FEARG_1,	    arg3_chanraw,
+    {"ch_sendraw",	2, 3, FEARG_1,	    arg23_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)},
@@ -1158,7 +1192,7 @@ static funcentry_T global_functions[] =
 			ret_number_bool,    f_complete_check},
     {"complete_info",	0, 1, FEARG_1,	    arg1_list_string,
 			ret_dict_any,	    f_complete_info},
-    {"confirm",		1, 4, FEARG_1,	    NULL,
+    {"confirm",		1, 4, FEARG_1,	    arg4_string_string_number_string,
 			ret_number,	    f_confirm},
     {"copy",		1, 1, FEARG_1,	    NULL,
 			ret_first_arg,	    f_copy},
@@ -1166,11 +1200,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,	    arg4_count,
+    {"count",		2, 4, FEARG_1,	    arg24_count,
 			ret_number,	    f_count},
     {"cscope_connection",0,3, 0,	    NULL,
 			ret_number,	    f_cscope_connection},
-    {"cursor",		1, 3, FEARG_1,	    arg3_cursor,
+    {"cursor",		1, 3, FEARG_1,	    arg13_cursor,
 			ret_number,	    f_cursor},
     {"debugbreak",	1, 1, FEARG_1,	    arg1_number,
 			ret_number,
@@ -1180,7 +1214,7 @@ static funcentry_T global_functions[] =
 	    NULL
 #endif
 			},
-    {"deepcopy",	1, 2, FEARG_1,	    arg2_deepcopy,
+    {"deepcopy",	1, 2, FEARG_1,	    arg12_deepcopy,
 			ret_first_arg,	    f_deepcopy},
     {"delete",		1, 2, FEARG_1,	    arg2_string,
 			ret_number_bool,    f_delete},
@@ -1206,7 +1240,7 @@ static funcentry_T global_functions[] =
 			ret_number_bool,    f_eventhandler},
     {"executable",	1, 1, FEARG_1,	    arg1_string,
 			ret_number,	    f_executable},
-    {"execute",		1, 2, FEARG_1,	    arg2_execute,
+    {"execute",		1, 2, FEARG_1,	    arg12_execute,
 			ret_string,	    f_execute},
     {"exepath",		1, 1, FEARG_1,	    arg1_string,
 			ret_string,	    f_exepath},
@@ -1230,7 +1264,7 @@ static funcentry_T global_functions[] =
 			ret_number_bool,    f_filereadable},
     {"filewritable",	1, 1, FEARG_1,	    arg1_string,
 			ret_number,	    f_filewritable},
-    {"filter",		2, 2, FEARG_1,	    NULL,
+    {"filter",		2, 2, FEARG_1,	    arg2_mapfilter,
 			ret_first_arg,	    f_filter},
     {"finddir",		1, 3, FEARG_1,	    arg3_string_string_nr,
 			ret_string,	    f_finddir},
@@ -1368,11 +1402,11 @@ static funcentry_T global_functions[] =
 			ret_number,	    f_getwinposy},
     {"getwinvar",	2, 3, FEARG_1,	    arg3_number_string_any,
 			ret_any,	    f_getwinvar},
-    {"glob",		1, 4, FEARG_1,	    arg4_glob,
+    {"glob",		1, 4, FEARG_1,	    arg14_glob,
 			ret_any,	    f_glob},
     {"glob2regpat",	1, 1, FEARG_1,	    arg1_string,
 			ret_string,	    f_glob2regpat},
-    {"globpath",	2, 5, FEARG_2,	    arg5_globpath,
+    {"globpath",	2, 5, FEARG_2,	    arg25_globpath,
 			ret_any,	    f_globpath},
     {"has",		1, 2, 0,	    arg2_string_bool,
 			ret_number_bool,    f_has},
@@ -1382,13 +1416,13 @@ static funcentry_T global_functions[] =
 			ret_number,	    f_haslocaldir},
     {"hasmapto",	1, 3, FEARG_1,	    arg3_string_string_bool,
 			ret_number_bool,    f_hasmapto},
-    {"highlightID",	1, 1, FEARG_1,	    NULL,	// obsolete
+    {"highlightID",	1, 1, FEARG_1,	    arg1_string,	// obsolete
 			ret_number,	    f_hlID},
-    {"highlight_exists",1, 1, FEARG_1,	    NULL,	// obsolete
+    {"highlight_exists",1, 1, FEARG_1,	    arg1_string,	// obsolete
 			ret_number_bool,    f_hlexists},
     {"histadd",		2, 2, FEARG_2,	    arg2_string,
 			ret_number_bool,    f_histadd},
-    {"histdel",		1, 2, FEARG_1,	    NULL,
+    {"histdel",		1, 2, FEARG_1,	    arg2_string_string_or_number,
 			ret_number_bool,    f_histdel},
     {"histget",		1, 2, FEARG_1,	    arg2_string_number,
 			ret_string,	    f_histget},
@@ -1404,7 +1438,7 @@ static funcentry_T global_functions[] =
 			ret_string,	    f_iconv},
     {"indent",		1, 1, FEARG_1,	    arg1_lnum,
 			ret_number,	    f_indent},
-    {"index",		2, 4, FEARG_1,	    arg4_index,
+    {"index",		2, 4, FEARG_1,	    arg24_index,
 			ret_number,	    f_index},
     {"input",		1, 3, FEARG_1,	    arg3_string,
 			ret_string,	    f_input},
@@ -1418,7 +1452,7 @@ static funcentry_T global_functions[] =
 			ret_number_bool,    f_inputsave},
     {"inputsecret",	1, 2, FEARG_1,	    arg2_string,
 			ret_string,	    f_inputsecret},
-    {"insert",		2, 3, FEARG_1,	    arg3_insert,
+    {"insert",		2, 3, FEARG_1,	    arg23_insert,
 			ret_first_arg,	    f_insert},
     {"interrupt",	0, 0, 0,	    NULL,
 			ret_void,	    f_interrupt},
@@ -1440,7 +1474,7 @@ static funcentry_T global_functions[] =
 			ret_job_info,	    JOB_FUNC(f_job_info)},
     {"job_setoptions",	2, 2, FEARG_1,	    arg2_job_dict,
 			ret_void,	    JOB_FUNC(f_job_setoptions)},
-    {"job_start",	1, 2, FEARG_1,	    NULL,
+    {"job_start",	1, 2, FEARG_1,	    arg2_string_or_list_dict,
 			ret_job,	    JOB_FUNC(f_job_start)},
     {"job_status",	1, 1, FEARG_1,	    arg1_job,
 			ret_string,	    JOB_FUNC(f_job_status)},
@@ -1494,21 +1528,21 @@ static funcentry_T global_functions[] =
 		NULL
 #endif
 			},
-    {"map",		2, 2, FEARG_1,	    NULL,
+    {"map",		2, 2, FEARG_1,	    arg2_mapfilter,
 			ret_first_cont,	    f_map},
-    {"maparg",		1, 4, FEARG_1,	    arg4_maparg,
+    {"maparg",		1, 4, FEARG_1,	    arg14_maparg,
 			ret_maparg,	    f_maparg},
     {"mapcheck",	1, 3, FEARG_1,	    arg3_string_string_bool,
 			ret_string,	    f_mapcheck},
-    {"mapnew",		2, 2, FEARG_1,	    NULL,
+    {"mapnew",		2, 2, FEARG_1,	    arg2_mapfilter,
 			ret_first_cont,	    f_mapnew},
     {"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},
-    {"matchadd",	2, 5, FEARG_1,	    NULL,
+    {"matchadd",	2, 5, FEARG_1,	    arg25_matchadd,
 			ret_number,	    f_matchadd},
-    {"matchaddpos",	2, 5, FEARG_1,	    NULL,
+    {"matchaddpos",	2, 5, FEARG_1,	    arg25_matchaddpos,
 			ret_number,	    f_matchaddpos},
     {"matcharg",	1, 1, FEARG_1,	    arg1_number,
 			ret_list_string,    f_matcharg},
@@ -1604,7 +1638,7 @@ static funcentry_T global_functions[] =
 			ret_number,	    PROP_FUNC(f_popup_notification)},
     {"popup_setoptions", 2, 2, FEARG_1,	    arg2_number_dict_any,
 			ret_void,	    PROP_FUNC(f_popup_setoptions)},
-    {"popup_settext",	2, 2, FEARG_1,	    NULL,
+    {"popup_settext",	2, 2, FEARG_1,	    arg2_number_string_or_list,
 			ret_void,	    PROP_FUNC(f_popup_settext)},
     {"popup_show",	1, 1, FEARG_1,	    arg1_number,
 			ret_void,	    PROP_FUNC(f_popup_show)},
@@ -1682,7 +1716,7 @@ static funcentry_T global_functions[] =
 			ret_list_dict_any,  f_readdirex},
     {"readfile",	1, 3, FEARG_1,	    arg3_string_string_nr,
 			ret_list_string,    f_readfile},
-    {"reduce",		2, 3, FEARG_1,	    NULL,
+    {"reduce",		2, 3, FEARG_1,	    arg23_reduce,
 			ret_any,	    f_reduce},
     {"reg_executing",	0, 0, 0,	    NULL,
 			ret_string,	    f_reg_executing},
@@ -1694,7 +1728,7 @@ static funcentry_T global_functions[] =
 			ret_float,	    FLOAT_FUNC(f_reltimefloat)},
     {"reltimestr",	1, 1, FEARG_1,	    arg1_list_number,
 			ret_string,	    f_reltimestr},
-    {"remote_expr",	2, 4, FEARG_1,	    arg4_remote_expr,
+    {"remote_expr",	2, 4, FEARG_1,	    arg24_remote_expr,
 			ret_string,	    f_remote_expr},
     {"remote_foreground", 1, 1, FEARG_1,    arg1_string,
 			ret_string,	    f_remote_foreground},
@@ -1706,11 +1740,11 @@ static funcentry_T global_functions[] =
 			ret_string,	    f_remote_send},
     {"remote_startserver", 1, 1, FEARG_1,   arg1_string,
 			ret_void,	    f_remote_startserver},
-    {"remove",		2, 3, FEARG_1,	    arg3_remove,
+    {"remove",		2, 3, FEARG_1,	    arg23_remove,
 			ret_remove,	    f_remove},
     {"rename",		2, 2, FEARG_1,	    arg2_string,
 			ret_number_bool,    f_rename},
-    {"repeat",		2, 2, FEARG_1,	    NULL,
+    {"repeat",		2, 2, FEARG_1,	    arg2_repeat,
 			ret_first_arg,	    f_repeat},
     {"resolve",		1, 1, FEARG_1,	    arg1_string,
 			ret_string,	    f_resolve},
@@ -1750,7 +1784,7 @@ static funcentry_T global_functions[] =
 			ret_number,	    f_searchpair},
     {"searchpairpos",	3, 7, 0,	    NULL,
 			ret_list_number,    f_searchpairpos},
-    {"searchpos",	1, 5, FEARG_1,	    NULL,
+    {"searchpos",	1, 5, FEARG_1,	    arg15_search,
 			ret_list_number,    f_searchpos},
     {"server2client",	2, 2, FEARG_1,	    arg2_string,
 			ret_number_bool,    f_server2client},
@@ -1768,7 +1802,7 @@ static funcentry_T global_functions[] =
 			ret_void,	    f_setcharsearch},
     {"setcmdpos",	1, 1, FEARG_1,	    arg1_number,
 			ret_number_bool,    f_setcmdpos},
-    {"setcursorcharpos", 1, 3, FEARG_1,	    arg3_cursor,
+    {"setcursorcharpos", 1, 3, FEARG_1,	    arg13_cursor,
 			ret_number_bool,    f_setcursorcharpos},
     {"setdigraph",	2, 2, FEARG_1,	    arg2_string_number,
 			ret_bool,           f_setdigraph},
@@ -1780,13 +1814,13 @@ 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,	    arg4_setloclist,
+    {"setloclist",	2, 4, FEARG_2,	    arg24_setloclist,
 			ret_number_bool,    f_setloclist},
     {"setmatches",	1, 2, FEARG_1,	    arg2_list_any_number,
 			ret_number_bool,    f_setmatches},
     {"setpos",		2, 2, FEARG_2,	    arg2_string_list_nr,
 			ret_number_bool,    f_setpos},
-    {"setqflist",	1, 3, FEARG_1,	    arg3_setqflist,
+    {"setqflist",	1, 3, FEARG_1,	    arg13_setqflist,
 			ret_number_bool,    f_setqflist},
     {"setreg",		2, 3, FEARG_2,	    NULL,
 			ret_number_bool,    f_setreg},
@@ -1794,7 +1828,7 @@ static funcentry_T global_functions[] =
 			ret_void,	    f_settabvar},
     {"settabwinvar",	4, 4, FEARG_4,	    arg4_number_number_string_any,
 			ret_void,	    f_settabwinvar},
-    {"settagstack",	2, 3, FEARG_2,	    arg2_settagstack,
+    {"settagstack",	2, 3, FEARG_2,	    arg23_settagstack,
 			ret_number_bool,    f_settagstack},
     {"setwinvar",	3, 3, FEARG_3,	    arg3_number_string_any,
 			ret_void,	    f_setwinvar},
@@ -1814,11 +1848,11 @@ 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,	    arg2_sign_getplaced,
+    {"sign_getplaced",	0, 2, FEARG_1,	    arg02_sign_getplaced,
 			ret_list_dict_any,  SIGN_FUNC(f_sign_getplaced)},
-    {"sign_jump",	3, 3, FEARG_1,	    NULL,
+    {"sign_jump",	3, 3, FEARG_1,	    arg3_number_string_buffer,
 			ret_number,	    SIGN_FUNC(f_sign_jump)},
-    {"sign_place",	4, 5, FEARG_1,	    NULL,
+    {"sign_place",	4, 5, FEARG_1,	    arg45_sign_place,
 			ret_number,	    SIGN_FUNC(f_sign_place)},
     {"sign_placelist",	1, 1, FEARG_1,	    arg1_list_any,
 			ret_list_number,    SIGN_FUNC(f_sign_placelist)},
@@ -1834,9 +1868,9 @@ 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,	    arg3_slice,
+    {"slice",		2, 3, FEARG_1,	    arg23_slice,
 			ret_first_arg,	    f_slice},
-    {"sort",		1, 3, FEARG_1,	    NULL,
+    {"sort",		1, 3, FEARG_1,	    arg13_sortuniq,
 			ret_first_arg,	    f_sort},
     {"sound_clear",	0, 0, 0,	    NULL,
 			ret_void,	    SOUND_FUNC(f_sound_clear)},
@@ -1868,7 +1902,7 @@ 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,	    arg4_strpart,
+    {"strcharpart",	2, 4, FEARG_1,	    arg24_strpart,
 			ret_string,	    f_strcharpart},
     {"strchars",	1, 2, FEARG_1,	    arg2_string_bool,
 			ret_number,	    f_strchars},
@@ -1890,7 +1924,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,	    arg4_strpart,
+    {"strpart",		2, 4, FEARG_1,	    arg24_strpart,
 			ret_string,	    f_strpart},
     {"strptime",	2, 2, FEARG_1,	    arg2_string,
 			ret_number,
@@ -1924,9 +1958,9 @@ static funcentry_T global_functions[] =
 			ret_list_any,	    f_synconcealed},
     {"synstack",	2, 2, 0,	    arg2_lnum_number,
 			ret_list_number,    f_synstack},
-    {"system",		1, 2, FEARG_1,	    NULL,
+    {"system",		1, 2, FEARG_1,	    arg12_system,
 			ret_string,	    f_system},
-    {"systemlist",	1, 2, FEARG_1,	    NULL,
+    {"systemlist",	1, 2, FEARG_1,	    arg12_system,
 			ret_list_string,    f_systemlist},
     {"tabpagebuflist",	0, 1, FEARG_1,	    arg1_number,
 			ret_list_number,    f_tabpagebuflist},
@@ -1944,11 +1978,11 @@ static funcentry_T global_functions[] =
 			ret_float,	    FLOAT_FUNC(f_tanh)},
     {"tempname",	0, 0, 0,	    NULL,
 			ret_string,	    f_tempname},
-    {"term_dumpdiff",	2, 3, FEARG_1,	    NULL,
+    {"term_dumpdiff",	2, 3, FEARG_1,	    arg3_string_string_dict,
 			ret_number,	    TERM_FUNC(f_term_dumpdiff)},
     {"term_dumpload",	1, 2, FEARG_1,	    arg2_string_dict,
 			ret_number,	    TERM_FUNC(f_term_dumpload)},
-    {"term_dumpwrite",	2, 3, FEARG_2,	    NULL,
+    {"term_dumpwrite",	2, 3, FEARG_2,	    arg3_buffer_string_dict,
 			ret_void,	    TERM_FUNC(f_term_dumpwrite)},
     {"term_getaltscreen", 1, 1, FEARG_1,    arg1_buffer,
 			ret_number,	    TERM_FUNC(f_term_getaltscreen)},
@@ -2092,7 +2126,7 @@ static funcentry_T global_functions[] =
 			ret_string,	    f_undofile},
     {"undotree",	0, 0, 0,	    NULL,
 			ret_dict_any,	    f_undotree},
-    {"uniq",		1, 3, FEARG_1,	    NULL,
+    {"uniq",		1, 3, FEARG_1,	    arg13_sortuniq,
 			ret_list_any,	    f_uniq},
     {"values",		1, 1, FEARG_1,	    arg1_dict_any,
 			ret_list_any,	    f_values},
@@ -2144,7 +2178,7 @@ static funcentry_T global_functions[] =
 			ret_number,	    f_winwidth},
     {"wordcount",	0, 0, 0,	    NULL,
 			ret_dict_number,    f_wordcount},
-    {"writefile",	2, 3, FEARG_1,	    NULL,
+    {"writefile",	2, 3, FEARG_1,	    arg23_writefile,
 			ret_number_bool,    f_writefile},
     {"xor",		2, 2, FEARG_1,	    arg2_number,
 			ret_number,	    f_xor},
@@ -2802,7 +2836,13 @@ f_confirm(typval_T *argvars UNUSED, typv
     char_u	*typestr;
     int		error = FALSE;
 
-    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+    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_number_arg(argvars, 2) == FAIL
+			    || (argvars[2].v_type != VAR_UNKNOWN
+				&& check_for_opt_string_arg(argvars, 3) == FAIL))))))
 	return;
 
     message = tv_get_string_chk(&argvars[0]);
@@ -5998,9 +6038,9 @@ f_index(typval_T *argvars, typval_T *ret
     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_list_or_blob_arg(argvars, 0) == FAIL
+		|| (argvars[0].v_type == VAR_BLOB
+		    && 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)))
@@ -7536,6 +7576,13 @@ f_repeat(typval_T *argvars, typval_T *re
     char_u	*r;
     int		i;
 
+    if (in_vim9script()
+	    && (argvars[0].v_type != VAR_STRING
+		&& argvars[0].v_type != VAR_NUMBER
+		&& argvars[0].v_type != VAR_LIST
+		&& check_for_string_arg(argvars, 0) == FAIL))
+	return;
+
     n = (int)tv_get_number(&argvars[1]);
     if (argvars[0].v_type == VAR_LIST)
     {
@@ -7655,6 +7702,15 @@ search_cmn(typval_T *argvars, pos_T *mat
     int		use_skip = FALSE;
     pos_T	firstpos;
 
+    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_number_arg(argvars, 2) == FAIL
+			|| (argvars[2].v_type != VAR_UNKNOWN
+			    && check_for_opt_number_arg(argvars, 3) == FAIL)))))
+	goto theend;
+
     pat = tv_get_string(&argvars[0]);
     dir = get_search_arg(&argvars[1], flagsp);	// may set p_ws
     if (dir == 0)
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -2180,6 +2180,12 @@ f_writefile(typval_T *argvars, typval_T 
     if (check_secure())
 	return;
 
+    if (in_vim9script()
+	    && (check_for_list_or_blob_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL
+		|| check_for_opt_string_arg(argvars, 2) == FAIL))
+	return;
+
     if (argvars[0].v_type == VAR_LIST)
     {
 	list = argvars[0].vval.v_list;
--- a/src/globals.h
+++ b/src/globals.h
@@ -1673,7 +1673,6 @@ EXTERN char e_boolreq[]		INIT(= N_("E839
 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"));
--- a/src/job.c
+++ b/src/job.c
@@ -1899,6 +1899,12 @@ f_job_start(typval_T *argvars, typval_T 
     rettv->v_type = VAR_JOB;
     if (check_restricted() || check_secure())
 	return;
+
+    if (in_vim9script()
+	    && (check_for_string_or_list_arg(argvars, 0) == FAIL
+		|| check_for_opt_dict_arg(argvars, 1) == FAIL))
+	return;
+
     rettv->vval.v_job = job_start(argvars, NULL, NULL, NULL);
 }
 
--- a/src/list.c
+++ b/src/list.c
@@ -1540,12 +1540,6 @@ list_remove(typval_T *argvars, typval_T 
     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;
@@ -1806,6 +1800,12 @@ do_sort_uniq(typval_T *argvars, typval_T
     long	len;
     long	i;
 
+    if (in_vim9script()
+	    && (check_for_list_arg(argvars, 0) == FAIL
+		|| (argvars[1].v_type != VAR_UNKNOWN
+		    && check_for_opt_dict_arg(argvars, 2) == FAIL)))
+	return;
+
     // Pointer to current info struct used in compare function. Save and
     // restore the current one for nested calls.
     old_sortinfo = sortinfo;
@@ -2103,6 +2103,11 @@ filter_map(typval_T *argvars, typval_T *
     // map() and filter() return the first argument, also on failure.
     if (filtermap != FILTERMAP_MAPNEW)
 	copy_tv(&argvars[0], rettv);
+
+    if (in_vim9script()
+	    && (check_for_list_or_dict_or_blob_arg(argvars, 0) == FAIL))
+	return;
+
     if (filtermap == FILTERMAP_MAP && in_vim9script())
     {
 	// Check that map() does not change the type of the dict.
@@ -2463,6 +2468,13 @@ f_mapnew(typval_T *argvars, typval_T *re
 f_add(typval_T *argvars, typval_T *rettv)
 {
     rettv->vval.v_number = 1; // Default: Failed
+
+    if (in_vim9script()
+	    && (check_for_list_or_blob_arg(argvars, 0) == FAIL
+		|| (argvars[0].v_type == VAR_BLOB
+		    && check_for_number_arg(argvars, 1) == FAIL)))
+	return;
+
     if (argvars[0].v_type == VAR_LIST)
     {
 	list_T	*l = argvars[0].vval.v_list;
@@ -2799,6 +2811,13 @@ f_insert(typval_T *argvars, typval_T *re
     listitem_T	*item;
     int		error = FALSE;
 
+    if (in_vim9script()
+	    && (check_for_list_or_blob_arg(argvars, 0) == FAIL
+		|| (argvars[0].v_type == VAR_BLOB
+		    && check_for_number_arg(argvars, 1) == FAIL)
+		|| check_for_opt_number_arg(argvars, 2) == FAIL))
+	return;
+
     if (argvars[0].v_type == VAR_BLOB)
     {
 	int	    val, len;
@@ -2888,6 +2907,16 @@ f_remove(typval_T *argvars, typval_T *re
 {
     char_u	*arg_errmsg = (char_u *)N_("remove() argument");
 
+    if (in_vim9script()
+	    && (check_for_list_or_dict_or_blob_arg(argvars, 0) == FAIL
+		|| ((argvars[0].v_type == VAR_LIST
+			|| argvars[0].v_type == VAR_BLOB)
+		    && (check_for_number_arg(argvars, 1) == FAIL
+			|| check_for_opt_number_arg(argvars, 2) == FAIL))
+		|| (argvars[0].v_type == VAR_DICT
+		    && check_for_string_or_number_arg(argvars, 1) == FAIL)))
+	return;
+
     if (argvars[0].v_type == VAR_DICT)
 	dict_remove(argvars, rettv, arg_errmsg);
     else if (argvars[0].v_type == VAR_BLOB)
@@ -2907,6 +2936,9 @@ f_reverse(typval_T *argvars, typval_T *r
     list_T	*l;
     listitem_T	*li, *ni;
 
+    if (in_vim9script() && check_for_list_or_blob_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type == VAR_BLOB)
     {
 	blob_T	*b = argvars[0].vval.v_blob;
--- a/src/match.c
+++ b/src/match.c
@@ -1163,8 +1163,8 @@ f_matchadd(typval_T *argvars UNUSED, typ
 {
 # ifdef FEAT_SEARCH_EXTRA
     char_u	buf[NUMBUFLEN];
-    char_u	*grp = tv_get_string_buf_chk(&argvars[0], buf);	// group
-    char_u	*pat = tv_get_string_buf_chk(&argvars[1], buf);	// pattern
+    char_u	*grp;		// group
+    char_u	*pat;		// pattern
     int		prio = 10;	// default priority
     int		id = -1;
     int		error = FALSE;
@@ -1173,6 +1173,18 @@ f_matchadd(typval_T *argvars UNUSED, typ
 
     rettv->vval.v_number = -1;
 
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL
+		|| check_for_opt_number_arg(argvars, 2) == FAIL
+		|| (argvars[2].v_type != VAR_UNKNOWN
+		    && (check_for_opt_number_arg(argvars, 3) == FAIL
+			|| (argvars[3].v_type != VAR_UNKNOWN
+			    && check_for_opt_dict_arg(argvars, 4) == FAIL)))))
+	return;
+
+    grp = tv_get_string_buf_chk(&argvars[0], buf);	// group
+    pat = tv_get_string_buf_chk(&argvars[1], buf);	// pattern
     if (grp == NULL || pat == NULL)
 	return;
     if (argvars[2].v_type != VAR_UNKNOWN)
@@ -1217,6 +1229,16 @@ f_matchaddpos(typval_T *argvars UNUSED, 
 
     rettv->vval.v_number = -1;
 
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_list_arg(argvars, 1) == FAIL
+		|| check_for_opt_number_arg(argvars, 2) == FAIL
+		|| (argvars[2].v_type != VAR_UNKNOWN
+		    && (check_for_opt_number_arg(argvars, 3) == FAIL
+			|| (argvars[3].v_type != VAR_UNKNOWN
+			    && check_for_opt_dict_arg(argvars, 4) == FAIL)))))
+	return;
+
     group = tv_get_string_buf_chk(&argvars[0], buf);
     if (group == NULL)
 	return;
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2351,6 +2351,11 @@ get_cmd_output_as_rettv(
     if (check_restricted() || check_secure())
 	goto errret;
 
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_opt_string_or_number_arg(argvars, 1) == FAIL))
+	return;
+
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
 	/*
--- a/src/popupwin.c
+++ b/src/popupwin.c
@@ -2597,9 +2597,16 @@ f_popup_show(typval_T *argvars, typval_T
     void
 f_popup_settext(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    int		id = (int)tv_get_number(&argvars[0]);
-    win_T	*wp = find_popup_win(id);
-
+    int		id;
+    win_T	*wp;
+
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_string_or_list_arg(argvars, 1) == FAIL))
+	return;
+
+    id = (int)tv_get_number(&argvars[0]);
+    wp = find_popup_win(id);
     if (wp != NULL)
     {
 	if (argvars[1].v_type != VAR_STRING && argvars[1].v_type != VAR_LIST)
--- a/src/proto/typval.pro
+++ b/src/proto/typval.pro
@@ -20,7 +20,6 @@ int check_for_list_arg(typval_T *args, i
 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);
@@ -31,6 +30,8 @@ int check_for_opt_lnum_arg(typval_T *arg
 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);
 int check_for_string_or_list_arg(typval_T *args, int idx);
+int check_for_list_or_blob_arg(typval_T *args, int idx);
+int check_for_list_or_dict_or_blob_arg(typval_T *args, int idx);
 int check_for_buffer_or_dict_arg(typval_T *args, int idx);
 char_u *tv_get_string(typval_T *varp);
 char_u *tv_get_string_strict(typval_T *varp);
--- a/src/sign.c
+++ b/src/sign.c
@@ -2235,6 +2235,11 @@ f_sign_define(typval_T *argvars, typval_
 {
     char_u	*name;
 
+    if (in_vim9script()
+	    && (check_for_string_or_list_arg(argvars, 0) == FAIL
+		|| check_for_opt_dict_arg(argvars, 1) == FAIL))
+	return;
+
     if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_UNKNOWN)
     {
 	// Define multiple signs
@@ -2363,6 +2368,12 @@ f_sign_jump(typval_T *argvars, typval_T 
 
     rettv->vval.v_number = -1;
 
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL
+		|| check_for_buffer_arg(argvars, 2) == FAIL))
+	return;
+
     // Sign identifier
     sign_id = (int)tv_get_number_chk(&argvars[0], &notanum);
     if (notanum)
@@ -2530,6 +2541,14 @@ f_sign_place(typval_T *argvars, typval_T
 
     rettv->vval.v_number = -1;
 
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL
+		|| check_for_string_arg(argvars, 2) == FAIL
+		|| check_for_buffer_arg(argvars, 3) == FAIL
+		|| check_for_opt_dict_arg(argvars, 4) == FAIL))
+	return;
+
     if (argvars[4].v_type != VAR_UNKNOWN
 	    && (argvars[4].v_type != VAR_DICT
 		|| ((dict = argvars[4].vval.v_dict) == NULL)))
--- a/src/terminal.c
+++ b/src/terminal.c
@@ -4756,7 +4756,7 @@ dump_term_color(FILE *fd, VTermColor *co
     void
 f_term_dumpwrite(typval_T *argvars, typval_T *rettv UNUSED)
 {
-    buf_T	*buf = term_get_buf(argvars, "term_dumpwrite()");
+    buf_T	*buf;
     term_T	*term;
     char_u	*fname;
     int		max_height = 0;
@@ -4771,6 +4771,14 @@ f_term_dumpwrite(typval_T *argvars, typv
 
     if (check_restricted() || check_secure())
 	return;
+
+    if (in_vim9script()
+	    && (check_for_buffer_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL
+		|| check_for_opt_dict_arg(argvars, 2) == FAIL))
+	return;
+
+    buf = term_get_buf(argvars, "term_dumpwrite()");
     if (buf == NULL)
 	return;
     term = buf->b_term;
@@ -5643,6 +5651,12 @@ term_swap_diff()
     void
 f_term_dumpdiff(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL
+		|| check_for_opt_dict_arg(argvars, 2) == FAIL))
+	return;
+
     term_load_dump(argvars, rettv, TRUE);
 }
 
--- a/src/testdir/test_blob.vim
+++ b/src/testdir/test_blob.vim
@@ -357,13 +357,13 @@ func Test_blob_add()
       VAR b = 0z0011
       call add(b, [9])
   END
-  call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1012:', 'E745:'])
+  call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1012:', 'E1210:'])
 
   let lines =<< trim END
       VAR b = 0z0011
       call add("", 0x01)
   END
-  call CheckLegacyAndVim9Failure(lines, 'E897:')
+  call CheckLegacyAndVim9Failure(lines, ['E897:', 'E1013:', 'E1211:'])
 
   let lines =<< trim END
       add(test_null_blob(), 0x22)
@@ -519,7 +519,7 @@ func Test_blob_insert()
       VAR b = 0zDEADBEEF
       call insert(b, 0, [9])
   END
-  call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E745:'])
+  call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E1210:'])
 
   let lines =<< trim END
       VAR b = 0zDEADBEEF
@@ -537,7 +537,7 @@ func Test_blob_insert()
       VAR b = 0zDEADBEEF
       call insert(b, [])
   END
-  call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E745:'])
+  call CheckLegacyAndVim9Failure(lines, ['E745:', 'E1013:', 'E1210:'])
 
   let lines =<< trim END
       insert(test_null_blob(), 0x33)
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -75,6 +75,11 @@ def Test_abs()
   endif
 enddef
 
+def Test_add()
+  CheckDefAndScriptFailure2(['add({}, 1)'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<unknown>', 'E1211: List required for argument 1')
+  CheckDefFailure(['add([1], "a")'], 'E1012: Type mismatch; expected number but got string')
+enddef
+
 def Test_add_blob()
   var b1: blob = 0z12
   add(b1, 0x34)
@@ -398,7 +403,7 @@ 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(1, "a")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: 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
@@ -407,7 +412,7 @@ 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(1, "")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: 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
@@ -417,7 +422,7 @@ 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(1, "a")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: 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
 enddef
@@ -492,7 +497,7 @@ 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(1, "a")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: 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
@@ -501,7 +506,7 @@ 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(1, "")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: 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
@@ -614,6 +619,10 @@ def Test_confirm()
   assert_fails('confirm(true)', 'E1174:')
   assert_fails('confirm("yes", true)', 'E1174:')
   assert_fails('confirm("yes", "maybe", 2, true)', 'E1174:')
+  CheckDefAndScriptFailure2(['confirm(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['confirm("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['confirm("a", "b", "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['confirm("a", "b", 3, 4)'], 'E1013: Argument 4: type mismatch, expected string but got number', 'E1174: String required for argument 4')
 enddef
 
 def Test_copy_return_type()
@@ -1027,6 +1036,13 @@ def Wrong_dict_key_type(items: list<numb
   return filter(items, (_, val) => get({[val]: 1}, 'x'))
 enddef
 
+def Test_filter()
+  CheckDefAndScriptFailure2(['filter(1.1, "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got float', 'E1211: List required for argument 1')
+  assert_equal([], filter([1, 2, 3], '0'))
+  assert_equal([1, 2, 3], filter([1, 2, 3], '1'))
+  assert_equal({b: 20}, filter({a: 10, b: 20}, 'v:val == 20'))
+enddef
+
 def Test_filter_wrong_dict_key_type()
   assert_fails('Wrong_dict_key_type([1, v:null, 3])', 'E1013:')
 enddef
@@ -1426,6 +1442,11 @@ def Test_histadd()
   assert_equal('skyblue', histget('/', -1))
 enddef
 
+def Test_histdel()
+  CheckDefAndScriptFailure2(['histdel(1, "x")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['histdel(":", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2')
+enddef
+
 def Test_histget()
   CheckDefAndScriptFailure2(['histget(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
   CheckDefAndScriptFailure2(['histget("a", "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
@@ -1462,8 +1483,10 @@ 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')
+  CheckDefFailure(['index(["1"], 1)'], 'E1013: Argument 2: type mismatch, expected string but got number')
+  CheckDefAndScriptFailure2(['index(0z10, "b")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
+  CheckDefAndScriptFailure2(['index([1], 1, "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['index(0z1020, 10, 1, 2)'], 'E1013: Argument 4: type mismatch, expected bool but got number', 'E1212: Bool required for argument 4')
 enddef
 
 def Test_input()
@@ -1596,7 +1619,7 @@ 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_channel(), {})'], 'E1013: Argument 1: type mismatch, expected job but got channel', 'E1218: 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
@@ -1615,7 +1638,7 @@ 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("a")'], 'E1013: Argument 1: type mismatch, expected job but got string', 'E1218: 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
@@ -1689,6 +1712,11 @@ 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()
+  CheckDefAndScriptFailure2(['map("x", "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['map(1, "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1')
+enddef
+
 def Test_map_failure()
   CheckFeature job
 
@@ -1798,6 +1826,11 @@ def Test_mapcheck()
   CheckDefAndScriptFailure2(['mapcheck("a", "b", 2)'], 'E1013: Argument 3: type mismatch, expected bool but got number', 'E1212: Bool required for argument 3')
 enddef
 
+def Test_mapnew()
+  CheckDefAndScriptFailure2(['mapnew("x", "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['mapnew(1, "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1')
+enddef
+
 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')
@@ -1819,6 +1852,23 @@ def Test_match()
   assert_equal(5, match(['a', 'b', 'c', 'b', 'd', 'b'], 'b', 2, 2))
 enddef
 
+def Test_matchadd()
+  CheckDefAndScriptFailure2(['matchadd(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['matchadd("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['matchadd("a", "b", "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['matchadd("a", "b", 1, "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
+  CheckDefAndScriptFailure2(['matchadd("a", "b", 1, 1, [])'], 'E1013: Argument 5: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 5')
+enddef
+
+def Test_matchaddpos()
+  CheckDefAndScriptFailure2(['matchaddpos(1, [1])'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['matchaddpos("a", "b")'], 'E1013: Argument 2: type mismatch, expected list<number> but got string', 'E1211: List required for argument 2')
+  CheckDefFailure(['matchaddpos("a", ["2"])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<string>')
+  CheckDefAndScriptFailure2(['matchaddpos("a", [1], "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['matchaddpos("a", [1], 1, "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
+  CheckDefAndScriptFailure2(['matchaddpos("a", [1], 1, 1, [])'], 'E1013: Argument 5: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 5')
+enddef
+
 def Test_matcharg()
   CheckDefFailure(['matcharg("x")'], 'E1013: Argument 1: type mismatch, expected number but got string')
 enddef
@@ -2074,6 +2124,11 @@ def Test_popup_setoptions()
   CheckDefAndScriptFailure2(['popup_setoptions(1, [])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<unknown>', 'E1206: Dictionary required for argument 2')
 enddef
 
+def Test_popup_settext()
+  CheckDefAndScriptFailure2(['popup_settext("x", [])'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['popup_settext(1, 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+enddef
+
 def Test_popup_show()
   CheckDefAndScriptFailure2(['popup_show("a")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1030: Using a String as a Number')
   CheckDefAndScriptFailure2(['popup_show(true)'], 'E1013: Argument 1: type mismatch, expected number but got bool', 'E1138: Using a Bool as a Number')
@@ -2226,6 +2281,12 @@ def Test_readfile()
   CheckDefAndScriptFailure2(['readfile("a", "b", "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1030: Using a String as a Number')
 enddef
 
+def Test_reduce()
+  CheckDefAndScriptFailure2(['reduce({a: 10}, "1")'], 'E1013: Argument 1: type mismatch, expected list<any> but got dict<number>', 'E897: List or Blob required')
+  assert_equal(6, [1, 2, 3]->reduce((r, c) => r + c, 0))
+  assert_equal(11, 0z0506->reduce((r, c) => r + c, 0))
+enddef
+
 def Test_reltime()
   CheckFeature reltime
 
@@ -2316,7 +2377,7 @@ def Test_remove_const_list()
 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("a", 1)'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
   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')
@@ -2354,14 +2415,22 @@ def Test_rename()
   CheckDefFailure(['rename("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number')
 enddef
 
+def Test_repeat()
+  CheckDefAndScriptFailure2(['repeat(1.1, 2)'], 'E1013: Argument 1: type mismatch, expected string but got float', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['repeat({a: 10}, 2)'], 'E1013: Argument 1: type mismatch, expected string but got dict<', 'E1174: String required for argument 1')
+  assert_equal('aaa', repeat('a', 3))
+  assert_equal('111', repeat(1, 3))
+  assert_equal([1, 1, 1], repeat([1], 3))
+enddef
+
 def Test_resolve()
   CheckDefFailure(['resolve([])'], 'E1013: Argument 1: type mismatch, expected string but got list<unknown>')
   assert_equal('SomeFile', resolve('SomeFile'))
 enddef
 
 def Test_reverse()
-  CheckDefAndScriptFailure2(['reverse(10)'], 'E1013: Argument 1: type mismatch, expected list<any> but got number', 'E899: Argument of reverse() must be a List or Blob')
-  CheckDefAndScriptFailure2(['reverse("abc")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E899: Argument of reverse() must be a List or Blob')
+  CheckDefAndScriptFailure2(['reverse(10)'], 'E1013: Argument 1: type mismatch, expected list<any> but got number', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['reverse("abc")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
 enddef
 
 def Test_reverse_return_type()
@@ -2436,6 +2505,10 @@ def Test_search()
   normal 0
   assert_equal([0, 0], searchpos('this', '', 0, 0, 'col(".") > col'))
   bwipe!
+  CheckDefAndScriptFailure2(['search(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['search("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['search("a", "b", "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['search("a", "b", 3, "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
 enddef
 
 def Test_searchcount()
@@ -2498,6 +2571,13 @@ def Test_searchpair()
   bwipe!
 enddef
 
+def Test_searchpos()
+  CheckDefAndScriptFailure2(['searchpos(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['searchpos("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['searchpos("a", "b", "c")'], 'E1013: Argument 3: type mismatch, expected number but got string', 'E1210: Number required for argument 3')
+  CheckDefAndScriptFailure2(['searchpos("a", "b", 3, "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4')
+enddef
+
 def Test_server2client()
   CheckFeature clientserver
   CheckEnv DISPLAY
@@ -2718,9 +2798,9 @@ def Test_shiftwidth()
 enddef
 
 def Test_sign_define()
-  CheckDefAndScriptFailure2(['sign_define({"a": 10})'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E731: Using a Dictionary as a String')
-  CheckDefAndScriptFailure2(['sign_define({"a": 10}, "b")'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E731: Using a Dictionary as a String')
-  CheckDefAndScriptFailure2(['sign_define("a", ["b"])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E715: Dictionary required')
+  CheckDefAndScriptFailure2(['sign_define({"a": 10})'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['sign_define({"a": 10}, "b")'], 'E1013: Argument 1: type mismatch, expected string but got dict<number>', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['sign_define("a", ["b"])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2')
 enddef
 
 def Test_sign_getdefined()
@@ -2734,6 +2814,20 @@ def Test_sign_getplaced()
   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_jump()
+  CheckDefAndScriptFailure2(['sign_jump("a", "b", "c")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['sign_jump(1, 2, 3)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['sign_jump(1, "b", true)'], 'E1013: Argument 3: type mismatch, expected string but got bool', 'E1174: String required for argument 3')
+enddef
+
+def Test_sign_place()
+  CheckDefAndScriptFailure2(['sign_place("a", "b", "c", "d")'], 'E1013: Argument 1: type mismatch, expected number but got string', 'E1210: Number required for argument 1')
+  CheckDefAndScriptFailure2(['sign_place(1, 2, "c", "d")'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['sign_place(1, "b", 3, "d")'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3')
+  CheckDefAndScriptFailure2(['sign_place(1, "b", "c", 1.1)'], 'E1013: Argument 4: type mismatch, expected string but got float', 'E1174: String required for argument 4')
+  CheckDefAndScriptFailure2(['sign_place(1, "b", "c", "d", [1])'], 'E1013: Argument 5: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 5')
+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')
@@ -2825,6 +2919,8 @@ def Test_sort_argument()
     assert_equal([1, 2, 3, 4, 5, 6, 7, 8], l)
   END
   CheckDefAndScriptSuccess(lines)
+  CheckDefAndScriptFailure2(['sort("a")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['sort([1], "", [1])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3')
 enddef
 
 def Test_spellbadword()
@@ -3017,6 +3113,16 @@ def Test_synstack()
   CheckDefAndScriptFailure2(['synstack(1, "a")'], 'E1013: Argument 2: type mismatch, expected number but got string', 'E1210: Number required for argument 2')
 enddef
 
+def Test_system()
+  CheckDefAndScriptFailure2(['system(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['system("a", {})'], 'E1013: Argument 2: type mismatch, expected string but got dict<unknown>', 'E1174: String required for argument 2')
+enddef
+
+def Test_systemlist()
+  CheckDefAndScriptFailure2(['systemlist(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['systemlist("a", {})'], 'E1013: Argument 2: type mismatch, expected string but got dict<unknown>', 'E1174: String required for argument 2')
+enddef
+
 def Test_tabpagebuflist()
   CheckDefFailure(['tabpagebuflist("t")'], 'E1013: Argument 1: type mismatch, expected number but got string')
   assert_equal([bufnr('')], tabpagebuflist())
@@ -3046,6 +3152,20 @@ def Test_term_dumpload()
   CheckDefAndScriptFailure2(['term_dumpload("a", ["b"])'], 'E1013: Argument 2: type mismatch, expected dict<any> but got list<string>', 'E1206: Dictionary required for argument 2')
 enddef
 
+def Test_term_dumpdiff()
+  CheckRunVimInTerminal
+  CheckDefAndScriptFailure2(['term_dumpdiff(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['term_dumpdiff("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['term_dumpdiff("a", "b", [1])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3')
+enddef
+
+def Test_term_dumpwrite()
+  CheckRunVimInTerminal
+  CheckDefAndScriptFailure2(['term_dumpwrite(true, "b")'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1174: String required for argument 1')
+  CheckDefAndScriptFailure2(['term_dumpwrite(1, 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2')
+  CheckDefAndScriptFailure2(['term_dumpwrite("a", "b", [1])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3')
+enddef
+
 def Test_term_getaltscreen()
   CheckRunVimInTerminal
   CheckDefAndScriptFailure2(['term_getaltscreen(true)'], 'E1013: Argument 1: type mismatch, expected string but got bool', 'E1138: Using a Bool as a Number')
@@ -3282,6 +3402,11 @@ def Test_undofile()
   assert_equal('.abc.un~', fnamemodify(undofile('abc'), ':t'))
 enddef
 
+def Test_uniq()
+  CheckDefAndScriptFailure2(['uniq("a")'], 'E1013: Argument 1: type mismatch, expected list<any> but got string', 'E1211: List required for argument 1')
+  CheckDefAndScriptFailure2(['uniq([1], "", [1])'], 'E1013: Argument 3: type mismatch, expected dict<any> but got list<number>', 'E1206: Dictionary required for argument 3')
+enddef
+
 def Test_values()
   CheckDefFailure(['values([])'], 'E1013: Argument 1: type mismatch, expected dict<any> but got list<unknown>')
   assert_equal([], {}->values())
--- a/src/typval.c
+++ b/src/typval.c
@@ -506,23 +506,6 @@ check_for_opt_dict_arg(typval_T *args, i
 }
 
 /*
- * 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
@@ -625,8 +608,7 @@ check_for_opt_lnum_arg(typval_T *args, i
 }
 
 /*
- * Give an error and return FAIL unless "args[idx]" is a string or
- * a blob.
+ * 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)
@@ -643,8 +625,7 @@ check_for_string_or_blob_arg(typval_T *a
 }
 
 /*
- * Give an error and return FAIL unless "args[idx]" is a string or
- * a list.
+ * Give an error and return FAIL unless "args[idx]" is a string or a list.
  */
     int
 check_for_string_or_list_arg(typval_T *args, int idx)
@@ -661,8 +642,45 @@ check_for_string_or_list_arg(typval_T *a
 }
 
 /*
- * Give an error and return FAIL unless "args[idx]" is a buffer
- * number or a dict.
+ * Give an error and return FAIL unless "args[idx]" is a list or a blob.
+ */
+    int
+check_for_list_or_blob_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_LIST && args[idx].v_type != VAR_BLOB)
+    {
+	if (idx >= 0)
+	    semsg(_(e_list_required_for_argument_nr), idx + 1);
+	else
+	    emsg(_(e_listreq));
+	return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a list or dict or a
+ * blob.
+ */
+    int
+check_for_list_or_dict_or_blob_arg(typval_T *args, int idx)
+{
+    if (args[idx].v_type != VAR_LIST
+	    && args[idx].v_type != VAR_DICT
+	    && args[idx].v_type != VAR_BLOB)
+    {
+	if (idx >= 0)
+	    semsg(_(e_list_required_for_argument_nr), idx + 1);
+	else
+	    emsg(_(e_listreq));
+	return FAIL;
+    }
+    return OK;
+}
+
+/*
+ * Give an error and return FAIL unless "args[idx]" is a buffer number or a
+ * dict.
  */
     int
 check_for_buffer_or_dict_arg(typval_T *args, int idx)
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3206,
+/**/
     3205,
 /**/
     3204,