Mercurial > vim
diff src/userfunc.c @ 24033:308d29307910 v8.2.2558
patch 8.2.2558: no error if a lambda argument shadows a variable
Commit: https://github.com/vim/vim/commit/057e84afe5bd37fe272bf7cfafca629ef9da1bd3
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Feb 28 16:55:11 2021 +0100
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 28 Feb 2021 17:00:04 +0100 |
parents | 90fbe1a3b23c |
children | 324408c61b20 |
line wrap: on
line diff
--- a/src/userfunc.c +++ b/src/userfunc.c @@ -55,6 +55,7 @@ func_tbl_get(void) * 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 @@ one_function_arg( garray_T *newargs, garray_T *argtypes, int types_optional, + evalarg_T *evalarg, int skip) { char_u *p = arg; @@ -81,13 +83,11 @@ one_function_arg( 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 @@ get_function_args( 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 @@ get_function_args( 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 @@ get_function_args( 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 @@ get_lambda_tv( // 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 @@ get_lambda_tv( 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 @@ get_lambda_tv( 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 @@ get_lambda_tv( 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 @@ define_function(exarg_T *eap, char_u *na ++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;