patch 8.2.3782: Vim9: no error if a function shadows a script variable

Problem:    Vim9: no error if a function shadows a script variable.
Solution:   Check the function doesn't shadow a variable. (closes #9310)
diff --git a/src/evalvars.c b/src/evalvars.c
index d91ec01..0410259 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -2712,7 +2712,7 @@
 		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 58cf020..b789b00 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -1896,6 +1896,17 @@
   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 @@
       echo 'local to function'
     enddef
   END
-  CheckScriptFailure(lines, 'E1073:')
+  CheckScriptFailure(lines, 'E1041:')
 
   lines =<< trim END
     vim9script
@@ -2231,7 +2242,7 @@
     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 4423ae5..52bacce 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -4134,19 +4134,41 @@
 				     || (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 cf57243..50fac52 100644
--- a/src/version.c
+++ b/src/version.c
@@ -754,6 +754,8 @@
 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 c4f6f15..6427380 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2782,6 +2782,7 @@
 #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