patch 8.2.2558: no error if a lambda argument shadows a variable
Problem: No error if a lambda argument shadows a variable.
Solution: Check that the argument name shadows a local, argument or script
variable. (closes #7898)
diff --git a/src/userfunc.c b/src/userfunc.c
index b49cef1..04c2641 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -55,6 +55,7 @@
* Get one function argument.
* If "argtypes" is not NULL also get the type: "arg: type".
* If "types_optional" is TRUE a missing type is OK, use "any".
+ * If "evalarg" is not NULL use it to check for an already declared name.
* Return a pointer to after the type.
* When something is wrong return "arg".
*/
@@ -64,6 +65,7 @@
garray_T *newargs,
garray_T *argtypes,
int types_optional,
+ evalarg_T *evalarg,
int skip)
{
char_u *p = arg;
@@ -81,13 +83,11 @@
return arg;
}
- // Vim9 script: cannot use script var name for argument.
- if (!skip && argtypes != NULL && script_var_exists(arg, p - arg,
- FALSE, NULL) == OK)
- {
- semsg(_(e_variable_already_declared_in_script), arg);
+ // Vim9 script: cannot use script var name for argument. In function: also
+ // check local vars and arguments.
+ if (!skip && argtypes != NULL && check_defined(arg, p - arg,
+ evalarg == NULL ? NULL : evalarg->eval_cctx, TRUE) == FAIL)
return arg;
- }
if (newargs != NULL && ga_grow(newargs, 1) == FAIL)
return arg;
@@ -173,6 +173,7 @@
garray_T *newargs,
garray_T *argtypes, // NULL unless using :def
int types_optional, // types optional if "argtypes" is not NULL
+ evalarg_T *evalarg, // context or NULL
int *varargs,
garray_T *default_args,
int skip,
@@ -247,7 +248,7 @@
arg = p;
p = one_function_arg(p, newargs, argtypes, types_optional,
- skip);
+ evalarg, skip);
if (p == arg)
break;
if (*skipwhite(p) == '=')
@@ -260,7 +261,8 @@
else
{
arg = p;
- p = one_function_arg(p, newargs, argtypes, types_optional, skip);
+ p = one_function_arg(p, newargs, argtypes, types_optional,
+ evalarg, skip);
if (p == arg)
break;
@@ -576,7 +578,7 @@
// be found after the arguments.
s = *arg + 1;
ret = get_function_args(&s, equal_arrow ? ')' : '-', NULL,
- types_optional ? &argtypes : NULL, types_optional,
+ types_optional ? &argtypes : NULL, types_optional, evalarg,
NULL, NULL, TRUE, NULL, NULL);
if (ret == FAIL || skip_arrow(s, equal_arrow, &ret_type, NULL) == NULL)
{
@@ -592,7 +594,7 @@
pnewargs = NULL;
*arg += 1;
ret = get_function_args(arg, equal_arrow ? ')' : '-', pnewargs,
- types_optional ? &argtypes : NULL, types_optional,
+ types_optional ? &argtypes : NULL, types_optional, evalarg,
&varargs, NULL, FALSE, NULL, NULL);
if (ret == FAIL
|| (s = skip_arrow(*arg, equal_arrow, &ret_type,
@@ -683,7 +685,6 @@
fp->uf_refcount = 1;
set_ufunc_name(fp, name);
- hash_add(&func_hashtab, UF2HIKEY(fp));
fp->uf_args = newargs;
ga_init(&fp->uf_def_args);
if (types_optional)
@@ -726,6 +727,8 @@
pt->pt_refcount = 1;
rettv->vval.v_partial = pt;
rettv->v_type = VAR_PARTIAL;
+
+ hash_add(&func_hashtab, UF2HIKEY(fp));
}
eval_lavars_used = old_eval_lavars;
@@ -3278,7 +3281,7 @@
++p;
if (get_function_args(&p, ')', &newargs,
eap->cmdidx == CMD_def ? &argtypes : NULL, FALSE,
- &varargs, &default_args, eap->skip,
+ NULL, &varargs, &default_args, eap->skip,
eap, &line_to_free) == FAIL)
goto errret_2;
whitep = p;