patch 8.2.2744: Vim9: no way to explicitly ignore an argument

Problem:    Vim9: no way to explicitly ignore an argument.
Solution:   Use the underscore as the name for an ignored argument.
diff --git a/src/errors.h b/src/errors.h
index e4836bc..d58da73 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -397,3 +397,5 @@
 	INIT(= N_("E1179: Failed to extract PWD from %s, check your shell's config related to OSC 7"));
 EXTERN char e_variable_arguments_type_must_be_list_str[]
 	INIT(= N_("E1180: Variable arguments type must be a list: %s"));
+EXTERN char e_cannot_use_underscore_here[]
+	INIT(= N_("E1181: Cannot use an underscore here"));
diff --git a/src/eval.c b/src/eval.c
index 05b6584..fe9d4ec 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3514,7 +3514,12 @@
 	{
 	    int	    flags = evalarg == NULL ? 0 : evalarg->eval_flags;
 
-	    if ((in_vim9script() ? **arg : *skipwhite(*arg)) == '(')
+	    if (in_vim9script() && len == 1 && *s == '_')
+	    {
+		emsg(_(e_cannot_use_underscore_here));
+		ret = FAIL;
+	    }
+	    else if ((in_vim9script() ? **arg : *skipwhite(*arg)) == '(')
 	    {
 		// "name(..."  recursive!
 		*arg = skipwhite(*arg);
diff --git a/src/evalvars.c b/src/evalvars.c
index 67abdcb..5869a82 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -3188,6 +3188,11 @@
 	goto failed;
     }
     var_in_vim9script = is_script_local && current_script_is_vim9();
+    if (var_in_vim9script && name[0] == '_' && name[1] == NUL)
+    {
+	emsg(_(e_cannot_use_underscore_here));
+	goto failed;
+    }
 
     di = find_var_in_ht(ht, 0, varname, TRUE);
 
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index e254f44..c02a324 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -2619,6 +2619,41 @@
   delfunc g:Broken
 enddef
 
+def Test_ignored_argument()
+  var lines =<< trim END
+      vim9script
+      def Ignore(_, _): string
+        return 'yes'
+      enddef
+      assert_equal('yes', Ignore(1, 2))
+
+      func Ok(_)
+        return a:_
+      endfunc
+      assert_equal('ok', Ok('ok'))
+
+      func Oktoo()
+        let _ = 'too'
+        return _
+      endfunc
+      assert_equal('too', Oktoo())
+  END
+  CheckScriptSuccess(lines)
+
+  lines =<< trim END
+      def Ignore(_: string): string
+        return _
+      enddef
+      defcompile
+  END
+  CheckScriptFailure(lines, 'E1181:', 1)
+
+  lines =<< trim END
+      var _ = 1
+  END
+  CheckDefAndScriptFailure(lines, 'E1181:', 1)
+enddef
+
 
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/version.c b/src/version.c
index a22312a..d5a9dc7 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2744,
+/**/
     2743,
 /**/
     2742,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index e5e3068..b005ff2 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -4416,6 +4416,12 @@
 
 	// "name" or "name()"
 	p = to_name_end(*arg, TRUE);
+	if (p - *arg == (size_t)1 && **arg == '_')
+	{
+	    emsg(_(e_cannot_use_underscore_here));
+	    return FAIL;
+	}
+
 	if (*p == '(')
 	{
 	    r = compile_call(arg, p - *arg, cctx, ppconst, 0);
@@ -6378,6 +6384,11 @@
 	    semsg(_(e_cannot_assign_to_constant), lhs.lhs_name);
 	    goto theend;
 	}
+	if (is_decl && lhs.lhs_name[0] == '_' && lhs.lhs_name[1] == NUL)
+	{
+	    emsg(_(e_cannot_use_underscore_here));
+	    goto theend;
+	}
 
 	if (!heredoc)
 	{