]> granicus.if.org Git - vim/commitdiff
patch 8.2.3782: Vim9: no error if a function shadows a script variable v8.2.3782
authorBram Moolenaar <Bram@vim.org>
Sat, 11 Dec 2021 13:54:46 +0000 (13:54 +0000)
committerBram Moolenaar <Bram@vim.org>
Sat, 11 Dec 2021 13:54:46 +0000 (13:54 +0000)
Problem:    Vim9: no error if a function shadows a script variable.
Solution:   Check the function doesn't shadow a variable. (closes #9310)

src/evalvars.c
src/testdir/test_vim9_script.vim
src/userfunc.c
src/version.c
src/vim.h

index d91ec014a22196dab85618e0c362a9bf74429df1..041025967a5d91b61f3448528638ea44d125cc47 100644 (file)
@@ -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);
 
index 58cf0202224bd26d52b5e0b7b6276eb0c27a6908..b789b00921efb4c33feae1e6d6dc31e9a08ac8cc 100644 (file)
@@ -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
index 4423ae59a5b836d43dc128cabfc028ffc1c78454..52bacce35e6d30f70b0c0b0b0fa162321345d578 100644 (file)
@@ -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
index cf5724387d3d5062e6d397fd1b1f6d138f8f0628..50fac523ab9cd5283384e9f6ac4db839e8ad0dd9 100644 (file)
@@ -753,6 +753,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3782,
 /**/
     3781,
 /**/
index c4f6f15d65f70ab856f83bfd259b9d6b5bab84b5..6427380f87dd30d158a8710b49c6c909a471eacb 100644 (file)
--- 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