summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-12-11 13:54:46 +0000
committerBram Moolenaar <Bram@vim.org>2021-12-11 13:54:46 +0000
commit052ff291d72bc9c176f9562f021d7e8e030e74c0 (patch)
tree7a2f1a88ee37ac45011d7d23de0135bf8b988e75
parenta416861c643b03fe5dec9f3bf8c1c9e054b5a9c7 (diff)
downloadvim-git-052ff291d72bc9c176f9562f021d7e8e030e74c0.tar.gz
patch 8.2.3782: Vim9: no error if a function shadows a script variablev8.2.3782
Problem: Vim9: no error if a function shadows a script variable. Solution: Check the function doesn't shadow a variable. (closes #9310)
-rw-r--r--src/evalvars.c2
-rw-r--r--src/testdir/test_vim9_script.vim15
-rw-r--r--src/userfunc.c36
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h1
5 files changed, 46 insertions, 10 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index d91ec014a..041025967 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -2712,7 +2712,7 @@ eval_variable(
type = sv->sv_type;
}
}
- else if (in_vim9script())
+ else if (in_vim9script() && (flags & EVAL_VAR_NO_FUNC) == 0)
{
ufunc_T *ufunc = find_func(name, FALSE, NULL);
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 58cf02022..b789b0092 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1896,6 +1896,17 @@ def Test_script_var_shadows_function()
CheckScriptFailure(lines, 'E1041:', 5)
enddef
+def Test_function_shadows_script_var()
+ var lines =<< trim END
+ vim9script
+ var Func = 1
+ def Func(): number
+ return 123
+ enddef
+ END
+ CheckScriptFailure(lines, 'E1041:', 3)
+enddef
+
def Test_script_var_shadows_command()
var lines =<< trim END
var undo = 1
@@ -2198,7 +2209,7 @@ def Test_func_overrules_import_fails()
echo 'local to function'
enddef
END
- CheckScriptFailure(lines, 'E1073:')
+ CheckScriptFailure(lines, 'E1041:')
lines =<< trim END
vim9script
@@ -2231,7 +2242,7 @@ def Test_func_redefine_fails()
vim9script
def Foo(): string
return 'foo'
- enddef
+ enddef
def Func()
var Foo = {-> 'lambda'}
enddef
diff --git a/src/userfunc.c b/src/userfunc.c
index 4423ae59a..52bacce35 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -4134,19 +4134,41 @@ define_function(exarg_T *eap, char_u *name_arg)
|| (fudi.fd_di->di_tv.v_type != VAR_FUNC
&& fudi.fd_di->di_tv.v_type != VAR_PARTIAL)))
{
+ char_u *name_base = arg;
+ int i;
+
if (*arg == K_SPECIAL)
- j = 3;
- else
- j = 0;
- while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
- : eval_isnamec(arg[j])))
- ++j;
- if (arg[j] != NUL)
+ {
+ name_base = vim_strchr(arg, '_');
+ if (name_base == NULL)
+ name_base = arg + 3;
+ else
+ ++name_base;
+ }
+ for (i = 0; name_base[i] != NUL && (i == 0
+ ? eval_isnamec1(name_base[i])
+ : eval_isnamec(name_base[i])); ++i)
+ ;
+ if (name_base[i] != NUL)
emsg_funcname((char *)e_invarg2, arg);
+
+ // In Vim9 script a function cannot have the same name as a
+ // variable.
+ if (vim9script && *arg == K_SPECIAL
+ && eval_variable(name_base, STRLEN(name_base), NULL, NULL,
+ EVAL_VAR_NOAUTOLOAD + EVAL_VAR_IMPORT
+ + EVAL_VAR_NO_FUNC) == OK)
+ {
+ semsg(_(e_redefining_script_item_str), name_base);
+ goto ret_free;
+ }
}
// Disallow using the g: dict.
if (fudi.fd_dict != NULL && fudi.fd_dict->dv_scope == VAR_DEF_SCOPE)
+ {
emsg(_("E862: Cannot use g: here"));
+ goto ret_free;
+ }
}
// This may get more lines and make the pointers into the first line
diff --git a/src/version.c b/src/version.c
index cf5724387..50fac523a 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3782,
+/**/
3781,
/**/
3780,
diff --git a/src/vim.h b/src/vim.h
index c4f6f15d6..6427380f8 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2782,6 +2782,7 @@ long elapsed(DWORD start_tick);
#define EVAL_VAR_VERBOSE 1 // may give error message
#define EVAL_VAR_NOAUTOLOAD 2 // do not use script autoloading
#define EVAL_VAR_IMPORT 4 // may return special variable for import
+#define EVAL_VAR_NO_FUNC 8 // do not look for a function
// Maximum number of characters that can be fuzzy matched
#define MAX_FUZZY_MATCHES 256