patch 8.2.2740: Vim9: lambda with varargs doesn't work

Problem:    Vim9: lambda with varargs doesn't work.
Solution:   Make "...name" work.  Require type to be a list.
diff --git a/src/errors.h b/src/errors.h
index 0225531..e4836bc 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -395,3 +395,5 @@
 	INIT(= N_("E1178: Cannot lock or unlock a local variable"));
 EXTERN char e_failed_to_extract_pwd_from_str_check_your_shell_config[]
 	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"));
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index b0669fe..d48cab4 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -791,10 +791,18 @@
 enddef
 
 def Test_call_lambda_args()
+  var lines =<< trim END
+    var Callback = (..._) => 'anything'
+    assert_equal('anything', Callback())
+    assert_equal('anything', Callback(1))
+    assert_equal('anything', Callback('a', 2))
+  END
+  CheckDefAndScriptSuccess(lines)
+
   CheckDefFailure(['echo ((i) => 0)()'],
                   'E119: Not enough arguments for function: ((i) => 0)()')
 
-  var lines =<< trim END
+  lines =<< trim END
       var Ref = (x: number, y: number) => x + y
       echo Ref(1, 'x')
   END
@@ -923,7 +931,7 @@
 
   lines =<< trim END
       vim9script
-      def Func(...l: any)
+      def Func(...l: list<any>)
         echo l
       enddef
       Func(0)
@@ -932,6 +940,15 @@
 
   lines =<< trim END
       vim9script
+      def Func(...l: any)
+        echo l
+      enddef
+      Func(0)
+  END
+  CheckScriptFailure(lines, 'E1180:', 2)
+
+  lines =<< trim END
+      vim9script
       def Func(..._l: list<string>)
         echo _l
       enddef
diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim
index 98f40bb..7155e8f 100644
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -3644,7 +3644,7 @@
 def Test_catch_exception_in_callback()
   var lines =<< trim END
     vim9script
-    def Callback(...l: any)
+    def Callback(...l: list<any>)
       try
         var x: string
         var y: string
@@ -3669,10 +3669,10 @@
   var lines =<< trim END
       vim9script
       var source: list<number>
-      def Out_cb(...l: any)
+      def Out_cb(...l: list<any>)
           eval [][0]
       enddef
-      def Exit_cb(...l: any)
+      def Exit_cb(...l: list<any>)
           sleep 1m
           source += l
       enddef
diff --git a/src/userfunc.c b/src/userfunc.c
index 81a73e2..8d06b49 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -68,6 +68,7 @@
 	garray_T    *argtypes,
 	int	    types_optional,
 	evalarg_T   *evalarg,
+	int	    is_vararg,
 	int	    skip)
 {
     char_u	*p = arg;
@@ -155,7 +156,8 @@
 	{
 	    if (type == NULL && types_optional)
 		// lambda arguments default to "any" type
-		type = vim_strsave((char_u *)"any");
+		type = vim_strsave((char_u *)
+					    (is_vararg ? "list<any>" : "any"));
 	    ((char_u **)argtypes->ga_data)[argtypes->ga_len++] = type;
 	}
     }
@@ -250,7 +252,7 @@
 
 		arg = p;
 		p = one_function_arg(p, newargs, argtypes, types_optional,
-								evalarg, skip);
+							  evalarg, TRUE, skip);
 		if (p == arg)
 		    break;
 		if (*skipwhite(p) == '=')
@@ -264,7 +266,7 @@
 	{
 	    arg = p;
 	    p = one_function_arg(p, newargs, argtypes, types_optional,
-								evalarg, skip);
+							 evalarg, FALSE, skip);
 	    if (p == arg)
 		break;
 
@@ -360,12 +362,14 @@
     static int
 parse_argument_types(ufunc_T *fp, garray_T *argtypes, int varargs)
 {
+    int len = 0;
+
     ga_init2(&fp->uf_type_list, sizeof(type_T *), 10);
     if (argtypes->ga_len > 0)
     {
 	// When "varargs" is set the last name/type goes into uf_va_name
 	// and uf_va_type.
-	int len = argtypes->ga_len - (varargs ? 1 : 0);
+	len = argtypes->ga_len - (varargs ? 1 : 0);
 
 	if (len > 0)
 	    fp->uf_arg_types = ALLOC_CLEAR_MULT(type_T *, len);
@@ -388,25 +392,35 @@
 		fp->uf_arg_types[i] = type;
 	    }
 	}
-	if (varargs)
-	{
-	    char_u *p;
-
-	    // Move the last argument "...name: type" to uf_va_name and
-	    // uf_va_type.
-	    fp->uf_va_name = ((char_u **)fp->uf_args.ga_data)
-						  [fp->uf_args.ga_len - 1];
-	    --fp->uf_args.ga_len;
-	    p = ((char_u **)argtypes->ga_data)[len];
-	    if (p == NULL)
-		// todo: get type from default value
-		fp->uf_va_type = &t_any;
-	    else
-		fp->uf_va_type = parse_type(&p, &fp->uf_type_list, TRUE);
-	    if (fp->uf_va_type == NULL)
-		return FAIL;
-	}
     }
+
+    if (varargs)
+    {
+	char_u *p;
+
+	// Move the last argument "...name: type" to uf_va_name and
+	// uf_va_type.
+	fp->uf_va_name = ((char_u **)fp->uf_args.ga_data)
+					      [fp->uf_args.ga_len - 1];
+	--fp->uf_args.ga_len;
+	p = ((char_u **)argtypes->ga_data)[len];
+	if (p == NULL)
+	    // TODO: get type from default value
+	    fp->uf_va_type = &t_list_any;
+	else
+	{
+	    fp->uf_va_type = parse_type(&p, &fp->uf_type_list, TRUE);
+	    if (fp->uf_va_type != NULL && fp->uf_va_type->tt_type != VAR_LIST)
+	    {
+		semsg(_(e_variable_arguments_type_must_be_list_str),
+					  ((char_u **)argtypes->ga_data)[len]);
+		return FAIL;
+	    }
+	}
+	if (fp->uf_va_type == NULL)
+	    return FAIL;
+    }
+
     return OK;
 }
 
@@ -1236,7 +1250,8 @@
 	ga_init(&fp->uf_def_args);
 	if (types_optional)
 	{
-	    if (parse_argument_types(fp, &argtypes, FALSE) == FAIL)
+	    if (parse_argument_types(fp, &argtypes,
+					   in_vim9script() && varargs) == FAIL)
 		goto errret;
 	    if (ret_type != NULL)
 	    {
@@ -1264,8 +1279,8 @@
 	if (sandbox)
 	    flags |= FC_SANDBOX;
 	// In legacy script a lambda can be called with more args than
-	// uf_args.ga_len.
-	fp->uf_varargs = !in_vim9script();
+	// uf_args.ga_len.  In Vim9 script "...name" has to be used.
+	fp->uf_varargs = !in_vim9script() || varargs;
 	fp->uf_flags = flags;
 	fp->uf_calls = 0;
 	fp->uf_script_ctx = current_sctx;
@@ -3190,7 +3205,7 @@
 	    msg_puts(", ");
 	msg_puts("...");
 	msg_puts((char *)fp->uf_va_name);
-	if (fp->uf_va_type)
+	if (fp->uf_va_type != NULL)
 	{
 	    char *tofree;
 
diff --git a/src/version.c b/src/version.c
index a2bd558..74a0ae6 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2740,
+/**/
     2739,
 /**/
     2738,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 00a8f56..2cfc127 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1856,7 +1856,8 @@
 		    continue;
 		expected = ufunc->uf_arg_types[i];
 	    }
-	    else if (ufunc->uf_va_type == NULL || ufunc->uf_va_type == &t_any)
+	    else if (ufunc->uf_va_type == NULL
+					   || ufunc->uf_va_type == &t_list_any)
 		// possibly a lambda or "...: any"
 		expected = &t_any;
 	    else
@@ -9069,7 +9070,7 @@
 	if (varargs)
 	{
 	    ufunc->uf_func_type->tt_args[argcount] =
-		    ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
+		   ufunc->uf_va_type == NULL ? &t_list_any : ufunc->uf_va_type;
 	    ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS;
 	}
     }
diff --git a/src/vim9execute.c b/src/vim9execute.c
index d6c4764..eddb90f 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1374,7 +1374,7 @@
 	// Check the type of the list items.
 	tv = STACK_TV_BOT(-1);
 	if (ufunc->uf_va_type != NULL
-		&& ufunc->uf_va_type != &t_any
+		&& ufunc->uf_va_type != &t_list_any
 		&& ufunc->uf_va_type->tt_member != &t_any
 		&& tv->vval.v_list != NULL)
 	{