patch 8.2.3229: Vim9: runtime and compile time type checks are not the same

Problem:    Vim9: runtime and compile time type checks are not the same.
Solution:   Add more runtime type checks for builtin functions. (Yegappan
            Lakshmanan, closes #8646)
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 2a9c972..7fc1821 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -762,7 +762,7 @@
 static argcheck_T arg3_string_number_number[] = {arg_string, arg_number, arg_number};
 static argcheck_T arg3_string_string_bool[] = {arg_string, arg_string, arg_bool};
 static argcheck_T arg3_string_string_dict[] = {arg_string, arg_string, arg_dict_any};
-static argcheck_T arg3_string_string_nr[] = {arg_string, arg_string, arg_number};
+static argcheck_T arg3_string_string_number[] = {arg_string, arg_string, arg_number};
 static argcheck_T arg4_list_number_number_number[] = {arg_list_string, arg_number, arg_number, arg_number};
 static argcheck_T arg4_number_number_string_any[] = {arg_number, arg_number, arg_string, NULL};
 static argcheck_T arg4_string_string_any_string[] = {arg_string, arg_string, NULL, arg_string};
@@ -811,7 +811,7 @@
 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 arg24_match_func[] = {arg_string_or_list_any, arg_string, arg_number, arg_number};
 
 
 /*
@@ -1340,9 +1340,9 @@
 			ret_number,	    f_filewritable},
     {"filter",		2, 2, FEARG_1,	    arg2_mapfilter,
 			ret_first_arg,	    f_filter},
-    {"finddir",		1, 3, FEARG_1,	    arg3_string_string_nr,
+    {"finddir",		1, 3, FEARG_1,	    arg3_string_string_number,
 			ret_string,	    f_finddir},
-    {"findfile",	1, 3, FEARG_1,	    arg3_string_string_nr,
+    {"findfile",	1, 3, FEARG_1,	    arg3_string_string_number,
 			ret_string,	    f_findfile},
     {"flatten",		1, 2, FEARG_1,	    arg2_list_any_number,
 			ret_list_any,	    f_flatten},
@@ -1608,7 +1608,7 @@
 			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,
+    {"match",		2, 4, FEARG_1,	    arg24_match_func,
 			ret_any,	    f_match},
     {"matchadd",	2, 5, FEARG_1,	    arg25_matchadd,
 			ret_number,	    f_matchadd},
@@ -1618,17 +1618,17 @@
 			ret_list_string,    f_matcharg},
     {"matchdelete",	1, 2, FEARG_1,	    arg2_number,
 			ret_number_bool,    f_matchdelete},
-    {"matchend",	2, 4, FEARG_1,	    arg4_match_func,
+    {"matchend",	2, 4, FEARG_1,	    arg24_match_func,
 			ret_number,	    f_matchend},
     {"matchfuzzy",	2, 3, FEARG_1,	    arg3_list_string_dict,
 			ret_list_string,    f_matchfuzzy},
     {"matchfuzzypos",	2, 3, FEARG_1,	    arg3_list_string_dict,
 			ret_list_any,	    f_matchfuzzypos},
-    {"matchlist",	2, 4, FEARG_1,	    arg4_match_func,
+    {"matchlist",	2, 4, FEARG_1,	    arg24_match_func,
 			ret_list_string,    f_matchlist},
-    {"matchstr",	2, 4, FEARG_1,	    arg4_match_func,
+    {"matchstr",	2, 4, FEARG_1,	    arg24_match_func,
 			ret_string,	    f_matchstr},
-    {"matchstrpos",	2, 4, FEARG_1,	    arg4_match_func,
+    {"matchstrpos",	2, 4, FEARG_1,	    arg24_match_func,
 			ret_list_any,	    f_matchstrpos},
     {"max",		1, 1, FEARG_1,	    arg1_list_or_dict,
 			ret_number,	    f_max},
@@ -1642,7 +1642,7 @@
 			},
     {"min",		1, 1, FEARG_1,	    arg1_list_or_dict,
 			ret_number,	    f_min},
-    {"mkdir",		1, 3, FEARG_1,	    arg3_string_string_nr,
+    {"mkdir",		1, 3, FEARG_1,	    arg3_string_string_number,
 			ret_number_bool,    f_mkdir},
     {"mode",		0, 1, FEARG_1,	    arg1_bool,
 			ret_string,	    f_mode},
@@ -1784,7 +1784,7 @@
 			ret_list_string,    f_readdir},
     {"readdirex",	1, 3, FEARG_1,	    arg3_string_any_dict,
 			ret_list_dict_any,  f_readdirex},
-    {"readfile",	1, 3, FEARG_1,	    arg3_string_string_nr,
+    {"readfile",	1, 3, FEARG_1,	    arg3_string_string_number,
 			ret_list_string,    f_readfile},
     {"reduce",		2, 3, FEARG_1,	    arg23_reduce,
 			ret_any,	    f_reduce},
@@ -1984,7 +1984,7 @@
 			},
     {"strgetchar",	2, 2, FEARG_1,	    arg2_string_number,
 			ret_number,	    f_strgetchar},
-    {"stridx",		2, 3, FEARG_1,	    arg3_string_string_nr,
+    {"stridx",		2, 3, FEARG_1,	    arg3_string_string_number,
 			ret_number,	    f_stridx},
     {"string",		1, 1, FEARG_1,	    NULL,
 			ret_string,	    f_string},
@@ -2000,7 +2000,7 @@
 	    NULL
 #endif
 			},
-    {"strridx",		2, 3, FEARG_1,	    arg3_string_string_nr,
+    {"strridx",		2, 3, FEARG_1,	    arg3_string_string_number,
 			ret_number,	    f_strridx},
     {"strtrans",	1, 1, FEARG_1,	    arg1_string,
 			ret_string,	    f_strtrans},
@@ -2180,7 +2180,7 @@
 			ret_string,	    f_toupper},
     {"tr",		3, 3, FEARG_1,	    arg3_string,
 			ret_string,	    f_tr},
-    {"trim",		1, 3, FEARG_1,	    arg3_string_string_nr,
+    {"trim",		1, 3, FEARG_1,	    arg3_string_string_number,
 			ret_string,	    f_trim},
     {"trunc",		1, 1, FEARG_1,	    arg1_float_or_nr,
 			ret_float,	    FLOAT_FUNC(f_trunc)},
@@ -2607,6 +2607,11 @@
     static void
 f_and(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
+	return;
+
     rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
 					& tv_get_number_chk(&argvars[1], NULL);
 }
@@ -2633,6 +2638,10 @@
 {
     if (balloonEval != NULL)
     {
+	if (in_vim9script()
+		&& check_for_string_or_list_arg(argvars, 0) == FAIL)
+	    return;
+
 	if (argvars[0].v_type == VAR_LIST
 # ifdef FEAT_GUI
 		&& !gui.in_use
@@ -2717,6 +2726,9 @@
 #else
     long	boff = 0;
 
+    if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
+	return;
+
     boff = tv_get_number(&argvars[0]) - 1;  // boff gets -1 on type error
     if (boff < 0)
 	rettv->vval.v_number = -1;
@@ -2822,6 +2834,10 @@
     pos_T	*fp;
     int		fnum = curbuf->b_fnum;
 
+    if (in_vim9script()
+	    && check_for_string_or_list_arg(argvars, 0) == FAIL)
+	return;
+
     fp = var2fpos(&argvars[0], FALSE, &fnum, charcol);
     if (fp != NULL && fnum == curbuf->b_fnum)
     {
@@ -2982,10 +2998,7 @@
     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_string_or_number_or_list_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)))
@@ -3071,6 +3084,9 @@
     int		pid;
 
     rettv->vval.v_number = FAIL;
+    if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
+	return;
+
     pid = (int)tv_get_number(&argvars[0]);
     if (pid == 0)
 	emsg(_(e_invarg));
@@ -3269,6 +3285,11 @@
 {
     char_u	buf[NUMBUFLEN];
 
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL))
+	return;
+
     rettv->vval.v_string = vim_strsave_escaped(tv_get_string(&argvars[0]),
 					 tv_get_string_buf(&argvars[1], buf));
     rettv->v_type = VAR_STRING;
@@ -3282,6 +3303,9 @@
 {
     char_u	*s, *p;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     s = tv_get_string_chk(&argvars[0]);
     if (s != NULL)
 	s = skipwhite(s);
@@ -3475,6 +3499,11 @@
     static void
 f_execute(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+	    && (check_for_string_or_list_arg(argvars, 0) == FAIL
+		|| check_for_opt_string_arg(argvars, 1) == FAIL))
+	return;
+
     execute_common(argvars, rettv, 0);
 }
 
@@ -3487,6 +3516,9 @@
     char_u	*p;
     int		n = FALSE;
 
+    if (in_vim9script() && check_for_nonempty_string_arg(argvars, 0) == FAIL)
+	return;
+
     p = tv_get_string(&argvars[0]);
     if (*p == '$')			// environment variable
     {
@@ -3631,6 +3663,9 @@
     char_u	*cmdstr;
     char	*errormsg = NULL;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     rettv->v_type = VAR_STRING;
     cmdstr = vim_strsave(tv_get_string(&argvars[0]));
 
@@ -3671,6 +3706,11 @@
     if (check_secure())
 	return;
 
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_opt_string_arg(argvars, 1) == FAIL))
+	return;
+
     keys = tv_get_string(&argvars[0]);
 
     if (argvars[1].v_type != VAR_UNKNOWN)
@@ -3760,6 +3800,9 @@
     static void
 f_fnameescape(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     rettv->vval.v_string = vim_strsave_fnameescape(
 					   tv_get_string(&argvars[0]), FALSE);
     rettv->v_type = VAR_STRING;
@@ -4029,6 +4072,9 @@
     static void
 f_garbagecollect(typval_T *argvars, typval_T *rettv UNUSED)
 {
+    if (in_vim9script() && check_for_opt_bool_arg(argvars, 0) == FAIL)
+	return;
+
     // This is postponed until we are back at the toplevel, because we may be
     // using Lists and Dicts internally.  E.g.: ":echo [garbagecollect()]".
     want_garbage_collect = TRUE;
@@ -4175,6 +4221,9 @@
     if (rettv_list_alloc(rettv) != OK)
 	return;
 
+    if (in_vim9script() && check_for_opt_buffer_arg(argvars, 0) == FAIL)
+	return;
+
 #ifdef FEAT_JUMPLIST
     if (argvars[0].v_type == VAR_UNKNOWN)
 	buf = curbuf;
@@ -4292,6 +4341,9 @@
     static void
 f_getcharpos(typval_T *argvars UNUSED, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     getpos_both(argvars, rettv, FALSE, TRUE);
 }
 
@@ -4318,8 +4370,12 @@
 f_getenv(typval_T *argvars, typval_T *rettv)
 {
     int	    mustfree = FALSE;
-    char_u  *p = vim_getenv(tv_get_string(&argvars[0]), &mustfree);
+    char_u  *p;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
+    p = vim_getenv(tv_get_string(&argvars[0]), &mustfree);
     if (p == NULL)
     {
 	rettv->v_type = VAR_SPECIAL;
@@ -4340,6 +4396,10 @@
 {
     rettv->v_type = VAR_STRING;
     rettv->vval.v_string = NULL;
+
+    if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL)
+	return;
+
 #ifdef FEAT_GUI
     if (gui.in_use)
     {
@@ -4385,6 +4445,12 @@
     if (rettv_list_alloc(rettv) != OK)
 	return;
 
+    if (in_vim9script()
+	    && (check_for_opt_number_arg(argvars, 0) == FAIL
+		|| (argvars[0].v_type != VAR_UNKNOWN
+		    && check_for_opt_number_arg(argvars, 1) == FAIL)))
+	return;
+
 #ifdef FEAT_JUMPLIST
     wp = find_tabwin(&argvars[0], &argvars[1], NULL);
     if (wp == NULL)
@@ -4433,12 +4499,18 @@
     static void
 f_getcurpos(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
+	return;
+
     getpos_both(argvars, rettv, TRUE, FALSE);
 }
 
     static void
 f_getcursorcharpos(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
+	return;
+
     getpos_both(argvars, rettv, TRUE, TRUE);
 }
 
@@ -4448,6 +4520,9 @@
     static void
 f_getpos(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     getpos_both(argvars, rettv, FALSE, FALSE);
 }
 
@@ -4464,10 +4539,11 @@
     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)))
+	    && (check_for_opt_string_arg(argvars, 0) == FAIL
+		|| (argvars[0].v_type != VAR_UNKNOWN
+		    && (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)
@@ -4526,6 +4602,9 @@
     char_u	buf[NUMBUFLEN + 2];
     long	reglen = 0;
 
+    if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
 	strregname = tv_get_string_chk(&argvars[0]);
@@ -4575,6 +4654,9 @@
     if (rettv_dict_alloc(rettv) != OK)
 	return;
 
+    if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
 	wp = find_win_by_nr_or_id(&argvars[0]);
@@ -4591,6 +4673,9 @@
     static void
 f_gettext(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type != VAR_STRING
 	    || argvars[0].vval.v_string == NULL
 	    || *argvars[0].vval.v_string == NUL)
@@ -6023,6 +6108,12 @@
     tabpage_T	*tp = NULL;
     win_T	*wp = NULL;
 
+    if (in_vim9script()
+	    && (check_for_opt_number_arg(argvars, 0) == FAIL
+		|| (argvars[0].v_type != VAR_UNKNOWN
+		    && check_for_opt_number_arg(argvars, 1) == FAIL)))
+	return;
+
     wp = find_tabwin(&argvars[0], &argvars[1], &tp);
 
     // Check for window-local and tab-local directories
@@ -6074,6 +6165,9 @@
     static void
 f_hlID(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     rettv->vval.v_number = syn_name2id(tv_get_string(&argvars[0]));
 }
 
@@ -6083,6 +6177,9 @@
     static void
 f_hlexists(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     rettv->vval.v_number = highlight_exists(tv_get_string(&argvars[0]));
 }
 
@@ -6214,6 +6311,13 @@
 	char_u	buf[NUMBUFLEN];
 	char_u	*defstr = (char_u *)"";
 
+	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_string_arg(argvars, 2) == FAIL)))
+	    return;
+
 	message = tv_get_string_chk(&argvars[0]);
 	if (argvars[1].v_type != VAR_UNKNOWN
 		&& (defstr = tv_get_string_buf_chk(&argvars[1], buf)) != NULL)
@@ -6258,6 +6362,9 @@
     if (no_console_input() && !is_not_a_term())
 	return;
 #endif
+    if (in_vim9script() && check_for_list_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type != VAR_LIST || argvars[0].vval.v_list == NULL)
     {
 	semsg(_(e_listarg), "inputlist()");
@@ -6332,6 +6439,11 @@
     static void
 f_inputsecret(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_opt_string_arg(argvars, 1) == FAIL))
+	return;
+
     ++cmdline_star;
     ++inputsecret_flag;
     f_input(argvars, rettv);
@@ -6354,6 +6466,9 @@
     static void
 f_invert(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
+	return;
+
     rettv->vval.v_number = ~tv_get_number_chk(&argvars[0], NULL);
 }
 
@@ -6585,6 +6700,9 @@
 #else
     linenr_T	lnum;
 
+    if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL)
+	return;
+
     lnum = tv_get_lnum(argvars);
     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1)
 	rettv->vval.v_number = -1;
@@ -6712,9 +6830,7 @@
     }
 
     if (in_vim9script()
-	    && ((argvars[0].v_type != VAR_STRING
-		    && argvars[0].v_type != VAR_LIST
-		    && check_for_string_arg(argvars, 0) == FAIL)
+	    && (check_for_string_or_list_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
@@ -6947,6 +7063,9 @@
     varnumber_T	i;
     int		error = FALSE;
 
+    if (in_vim9script() && check_for_list_or_dict_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type == VAR_LIST)
     {
 	list_T		*l;
@@ -7052,6 +7171,10 @@
 
     if (check_restricted() || check_secure())
 	return;
+
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     str = tv_get_string_buf(&argvars[0], buf);
     do_mzeval(str, rettv);
 }
@@ -7078,6 +7201,9 @@
 {
     linenr_T	lnum;
 
+    if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL)
+	return;
+
     for (lnum = tv_get_lnum(argvars); ; ++lnum)
     {
 	if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count)
@@ -7130,6 +7256,11 @@
     static void
 f_or(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
+	return;
+
     rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
 					| tv_get_number_chk(&argvars[1], NULL);
 }
@@ -7144,6 +7275,9 @@
     char_u	*str;
     char_u	buf[NUMBUFLEN];
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     str = tv_get_string_buf(&argvars[0], buf);
     do_perleval(str, rettv);
 }
@@ -7157,6 +7291,9 @@
 {
     linenr_T	lnum;
 
+    if (in_vim9script() && check_for_lnum_arg(argvars, 0) == FAIL)
+	return;
+
     lnum = tv_get_lnum(argvars);
     if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
 	lnum = 0;
@@ -7241,6 +7378,9 @@
     if (check_restricted() || check_secure())
 	return;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     if (p_pyx == 0)
 	p_pyx = 3;
 
@@ -7262,6 +7402,9 @@
     if (check_restricted() || check_secure())
 	return;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     if (p_pyx == 0)
 	p_pyx = 2;
 
@@ -7280,6 +7423,9 @@
     if (check_restricted() || check_secure())
 	return;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
 # if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
     init_pyxversion();
     if (p_pyx == 2)
@@ -7300,6 +7446,9 @@
     static void
 f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED)
 {
+    if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type == VAR_UNKNOWN)
 	srand_seed_for_testing_is_used = FALSE;
     else
@@ -7383,6 +7532,9 @@
     listitem_T	*lx, *ly, *lz, *lw;
     UINT32_T	x = 0, y, z, w, t, result;
 
+    if (in_vim9script() && check_for_opt_list_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type == VAR_UNKNOWN)
     {
 	// When no argument is given use the global seed list.
@@ -7449,6 +7601,10 @@
 
     if (rettv_list_alloc(rettv) == FAIL)
 	return;
+
+    if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type == VAR_UNKNOWN)
     {
 	init_srand(&x);
@@ -7483,6 +7639,13 @@
     varnumber_T	stride = 1;
     int		error = 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_number_arg(argvars, 2) == FAIL)))
+	return;
+
     start = tv_get_number_chk(&argvars[0], &error);
     if (argvars[1].v_type == VAR_UNKNOWN)
     {
@@ -7551,6 +7714,9 @@
     dict_T	*dict;
     list_T	*list;
 
+    if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
 	strregname = tv_get_string_chk(&argvars[0]);
@@ -7645,10 +7811,16 @@
 {
     char_u	buf[NUMBUFLEN];
 
+    rettv->vval.v_number = -1;
     if (check_restricted() || check_secure())
-	rettv->vval.v_number = -1;
-    else
-	rettv->vval.v_number = vim_rename(tv_get_string(&argvars[0]),
+	return;
+
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL))
+	return;
+
+    rettv->vval.v_number = vim_rename(tv_get_string(&argvars[0]),
 				      tv_get_string_buf(&argvars[1], buf));
 }
 
@@ -7666,10 +7838,8 @@
     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))
+	    && (check_for_string_or_number_or_list_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
 	return;
 
     n = (int)tv_get_number(&argvars[1]);
@@ -7932,6 +8102,9 @@
     char_u	*str;
     char_u	buf[NUMBUFLEN];
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     str = tv_get_string_buf(&argvars[0], buf);
     do_rubyeval(str, rettv);
 }
@@ -7947,6 +8120,11 @@
     int		col;
     int		c;
 
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
+	return;
+
     row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
     col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
     if (row < 0 || row >= screen_Rows
@@ -7968,6 +8146,11 @@
     int		off;
     int		c;
 
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
+	return;
+
     row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
     col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
     if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns)
@@ -7997,6 +8180,12 @@
 
     if (rettv_list_alloc(rettv) == FAIL)
 	return;
+
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
+	return;
+
     row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
     col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
     if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns)
@@ -8053,6 +8242,11 @@
     rettv->vval.v_string = NULL;
     rettv->v_type = VAR_STRING;
 
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
+	return;
+
     row = (int)tv_get_number_chk(&argvars[0], NULL) - 1;
     col = (int)tv_get_number_chk(&argvars[1], NULL) - 1;
     if (row < 0 || row >= screen_Rows || col < 0 || col >= screen_Columns)
@@ -8515,6 +8709,9 @@
     dictitem_T	*di;
     char_u	*csearch;
 
+    if (in_vim9script() && check_for_dict_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type != VAR_DICT)
     {
 	emsg(_(e_dictreq));
@@ -8593,6 +8790,12 @@
     int		mode = 0;
 
     rettv->vval.v_number = 0;
+
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_string_arg(argvars, 1) == FAIL))
+	return;
+
     fname = tv_get_string_chk(&argvars[0]);
     if (fname == NULL)
 	return;
@@ -8900,6 +9103,9 @@
 {
     char_u	*p;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     p = tv_get_string(&argvars[0]);
     rettv->vval.v_string = vim_strsave(
 				    sha256_bytes(p, (int)STRLEN(p), NULL, 0));
@@ -8934,6 +9140,9 @@
 {
     rettv->vval.v_number = 0;
 
+    if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
 	long	col;
@@ -8958,6 +9167,9 @@
 {
     char_u	*s;
 
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     rettv->v_type = VAR_STRING;
     s = tv_get_string(&argvars[0]);
 #ifdef FEAT_SPELL
@@ -8979,6 +9191,9 @@
 #ifdef FEAT_SPELL
     int		wo_spell_save = curwin->w_p_spell;
 
+    if (in_vim9script() && check_for_opt_string_arg(argvars, 0) == FAIL)
+	return;
+
     if (!curwin->w_p_spell)
     {
 	did_set_spelllang(curwin);
@@ -9298,6 +9513,9 @@
     static void
 f_swapinfo(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
+	return;
+
     if (rettv_dict_alloc(rettv) == OK)
 	get_b0_dict(tv_get_string(argvars), rettv->vval.v_dict);
 }
@@ -9311,6 +9529,10 @@
     buf_T	*buf;
 
     rettv->v_type = VAR_STRING;
+
+    if (in_vim9script() && check_for_buffer_arg(argvars, 0) == FAIL)
+	return;
+
     buf = tv_get_buf(&argvars[0], FALSE);
     if (buf == NULL || buf->b_ml.ml_mfp == NULL
 					|| buf->b_ml.ml_mfp->mf_fname == NULL)
@@ -9460,6 +9682,9 @@
     int		id;
 
 #ifdef FEAT_SYN_HL
+    if (in_vim9script() && check_for_number_arg(argvars, 0) == FAIL)
+	return;
+
     id = (int)tv_get_number(&argvars[0]);
 
     if (id > 0)
@@ -9584,6 +9809,9 @@
     tabpage_T	*tp;
     win_T	*wp = NULL;
 
+    if (in_vim9script() && check_for_opt_number_arg(argvars, 0) == FAIL)
+	return;
+
     if (argvars[0].v_type == VAR_UNKNOWN)
 	wp = firstwin;
     else
@@ -9634,6 +9862,11 @@
     char_u  *fname = NULL;
     char_u  *tag_pattern;
 
+    if (in_vim9script()
+	    && (check_for_string_arg(argvars, 0) == FAIL
+		|| check_for_opt_string_arg(argvars, 1) == FAIL))
+	return;
+
     tag_pattern = tv_get_string(&argvars[0]);
 
     rettv->vval.v_number = FALSE;
@@ -9690,6 +9923,10 @@
     int		fnum = curbuf->b_fnum;
     int		len;
 
+    if (in_vim9script()
+	    && check_for_string_or_list_arg(argvars, 0) == FAIL)
+	return;
+
     fp = var2fpos(&argvars[0], FALSE, &fnum, FALSE);
     if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count
 						    && fnum == curbuf->b_fnum)
@@ -9718,6 +9955,9 @@
 {
     char_u	str[2];
 
+    if (in_vim9script() && check_for_opt_bool_arg(argvars, 0) == FAIL)
+	return;
+
     rettv->v_type = VAR_STRING;
     str[0] = curbuf->b_visual_mode_eval;
     str[1] = NUL;
@@ -9767,6 +10007,11 @@
     static void
 f_xor(typval_T *argvars, typval_T *rettv)
 {
+    if (in_vim9script()
+	    && (check_for_number_arg(argvars, 0) == FAIL
+		|| check_for_number_arg(argvars, 1) == FAIL))
+	return;
+
     rettv->vval.v_number = tv_get_number_chk(&argvars[0], NULL)
 					^ tv_get_number_chk(&argvars[1], NULL);
 }