patch 8.2.4162: Vim9: no error for redefining function with export

Problem:    Vim9: no error for redefining function with export.
Solution:   Check for existing function with/without prefix. (closes #9577)
diff --git a/src/scriptfile.c b/src/scriptfile.c
index 5b1e43b..dec512a 100644
--- a/src/scriptfile.c
+++ b/src/scriptfile.c
@@ -2190,7 +2190,7 @@
 
 /*
  * If in a Vim9 autoload script return "name" with the autoload prefix for the
- * script.  If successful "name" is freed, the returned name is allocated.
+ * script.  If successful the returned name is allocated.
  * Otherwise it returns "name" unmodified.
  */
     char_u *
@@ -2221,7 +2221,6 @@
 	    {
 		vim_snprintf((char *)res, len, "%s%s",
 					     si->sn_autoload_prefix, basename);
-		vim_free(name);
 		return res;
 	    }
 	}
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index 6a38106..c26ccf8 100644
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -1440,6 +1440,80 @@
   &rtp = save_rtp
 enddef
 
+def Test_vim9script_autoload_duplicate()
+  mkdir('Xdir/autoload', 'p')
+
+  var lines =<< trim END
+     vim9script
+
+     export def Func()
+     enddef
+
+     def Func()
+     enddef
+  END
+  writefile(lines, 'Xdir/autoload/dupfunc.vim')
+  assert_fails('source Xdir/autoload/dupfunc.vim', 'E1073:')
+
+  lines =<< trim END
+     vim9script
+
+     def Func()
+     enddef
+
+     export def Func()
+     enddef
+  END
+  writefile(lines, 'Xdir/autoload/dup2func.vim')
+  assert_fails('source Xdir/autoload/dup2func.vim', 'E1073:')
+
+  lines =<< trim END
+     vim9script
+
+     def Func()
+     enddef
+
+     export var Func = 'asdf'
+  END
+  writefile(lines, 'Xdir/autoload/dup3func.vim')
+  assert_fails('source Xdir/autoload/dup3func.vim', 'E1041: Redefining script item Func')
+
+  lines =<< trim END
+     vim9script
+
+     export var Func = 'asdf'
+
+     def Func()
+     enddef
+  END
+  writefile(lines, 'Xdir/autoload/dup4func.vim')
+  assert_fails('source Xdir/autoload/dup4func.vim', 'E707:')
+
+  lines =<< trim END
+     vim9script
+
+     var Func = 'asdf'
+
+     export def Func()
+     enddef
+  END
+  writefile(lines, 'Xdir/autoload/dup5func.vim')
+  assert_fails('source Xdir/autoload/dup5func.vim', 'E707:')
+
+  lines =<< trim END
+     vim9script
+
+     export def Func()
+     enddef
+
+     var Func = 'asdf'
+  END
+  writefile(lines, 'Xdir/autoload/dup6func.vim')
+  assert_fails('source Xdir/autoload/dup6func.vim', 'E1041: Redefining script item Func')
+
+  delete('Xdir', 'rf')
+enddef
+
 def Test_import_autoload_postponed()
   mkdir('Xdir/autoload', 'p')
   var save_rtp = &rtp
diff --git a/src/userfunc.c b/src/userfunc.c
index 7d3bb29..014ec55 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -1911,6 +1911,12 @@
     {
 	size_t	len = STRLEN(si->sn_autoload_prefix) + STRLEN(name) + 1;
 	char_u	*auto_name;
+	char_u	*namep;
+
+	// skip a "<SNR>99_" prefix
+	namep = untrans_function_name(name);
+	if (namep == NULL)
+	    namep = name;
 
 	// An exported function in an autoload script is stored as
 	// "dir#path#name".
@@ -1921,7 +1927,7 @@
 	if (auto_name != NULL)
 	{
 	    vim_snprintf((char *)auto_name, len, "%s%s",
-						 si->sn_autoload_prefix, name);
+						si->sn_autoload_prefix, namep);
 	    hi = hash_find(&func_hashtab, auto_name);
 	    if (auto_name != buffer)
 		vim_free(auto_name);
@@ -4175,7 +4181,15 @@
 	// is stored with the legacy autoload name "dir#script#FuncName" so
 	// that it can also be found in legacy script.
 	if (is_export && name != NULL)
-	    name = may_prefix_autoload(name);
+	{
+	    char_u *prefixed = may_prefix_autoload(name);
+
+	    if (prefixed != NULL && prefixed != name)
+	    {
+		vim_free(name);
+		name = prefixed;
+	    }
+	}
     }
 
     // An error in a function call during evaluation of an expression in magic
@@ -4447,20 +4461,53 @@
     if (fudi.fd_dict == NULL)
     {
 	hashtab_T	*ht;
+	char_u		*find_name = name;
+	int		var_conflict = FALSE;
 
 	v = find_var(name, &ht, TRUE);
-	if (v != NULL && v->di_tv.v_type == VAR_FUNC)
+	if (v != NULL)
+	    var_conflict = TRUE;
+
+	if (SCRIPT_ID_VALID(current_sctx.sc_sid))
+	{
+	    scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
+
+	    if (si->sn_autoload_prefix != NULL)
+	    {
+		if (is_export)
+		{
+		    find_name = name + STRLEN(si->sn_autoload_prefix);
+		    v = find_var(find_name, &ht, TRUE);
+		    if (v != NULL)
+			var_conflict = TRUE;
+		}
+		else
+		{
+		    char_u *prefixed = may_prefix_autoload(name);
+
+		    if (prefixed != NULL)
+		    {
+			v = find_var(prefixed, &ht, TRUE);
+			if (v != NULL)
+			    var_conflict = TRUE;
+			vim_free(prefixed);
+		    }
+		}
+	    }
+	}
+	if (var_conflict)
 	{
 	    emsg_funcname(e_function_name_conflicts_with_variable_str, name);
 	    goto erret;
 	}
 
-	fp = find_func_even_dead(name, is_global);
+	fp = find_func_even_dead(find_name, is_global);
 	if (vim9script)
 	{
 	    char_u *uname = untrans_function_name(name);
 
-	    import = find_imported(uname == NULL ? name : uname, 0, FALSE, NULL);
+	    import = find_imported(uname == NULL ? name : uname, 0,
+								  FALSE, NULL);
 	}
 
 	if (fp != NULL || import != NULL)
diff --git a/src/version.c b/src/version.c
index fae00dc..7fd24f5 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4162,
+/**/
     4161,
 /**/
     4160,