patch 8.2.2753: Vim9: cannot ignore an item in assignment unpack

Problem:    Vim9: cannot ignore an item in assignment unpack.
Solution:   Allow using an underscore.
diff --git a/src/eval.c b/src/eval.c
index fe9d4ec..787243e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -3514,7 +3514,7 @@
 	{
 	    int	    flags = evalarg == NULL ? 0 : evalarg->eval_flags;
 
-	    if (in_vim9script() && len == 1 && *s == '_')
+	    if (evaluate && in_vim9script() && len == 1 && *s == '_')
 	    {
 		emsg(_(e_cannot_use_underscore_here));
 		ret = FAIL;
diff --git a/src/evalvars.c b/src/evalvars.c
index 5869a82..b8a4352 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -970,8 +970,8 @@
     {
 	arg = skipwhite(arg + 1);
 	++var_idx;
-	arg = ex_let_one(arg, &item->li_tv, TRUE, flags, (char_u *)",;]",
-								  op, var_idx);
+	arg = ex_let_one(arg, &item->li_tv, TRUE,
+			  flags | ASSIGN_UNPACK, (char_u *)",;]", op, var_idx);
 	item = item->li_next;
 	if (arg == NULL)
 	    return FAIL;
@@ -996,8 +996,8 @@
 	    l->lv_refcount = 1;
 	    ++var_idx;
 
-	    arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, flags,
-						   (char_u *)"]", op, var_idx);
+	    arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE,
+			    flags | ASSIGN_UNPACK, (char_u *)"]", op, var_idx);
 	    clear_tv(&ltv);
 	    if (arg == NULL)
 		return FAIL;
@@ -3190,7 +3190,9 @@
     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));
+	// For "[a, _] = list" the underscore is ignored.
+	if ((flags & ASSIGN_UNPACK) == 0)
+	    emsg(_(e_cannot_use_underscore_here));
 	goto failed;
     }
 
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index c35084d..958b7b9 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -256,6 +256,14 @@
     [v1, v2] = [1, 2]
     assert_equal(1, v1)
     assert_equal(2, v2)
+
+    [v1, _, v2, _] = [1, 99, 2, 77]
+    assert_equal(1, v1)
+    assert_equal(2, v2)
+
+    [v1, v2; _] = [1, 2, 3, 4, 5]
+    assert_equal(1, v1)
+    assert_equal(2, v2)
   END
   CheckDefAndScriptSuccess(lines)
 
diff --git a/src/version.c b/src/version.c
index d266a1a..c760738 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2753,
+/**/
     2752,
 /**/
     2751,
diff --git a/src/vim.h b/src/vim.h
index 7f4c99a..31e181a 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2152,10 +2152,11 @@
 } estack_arg_T;
 
 // Flags for assignment functions.
-#define ASSIGN_FINAL	1   // ":final"
-#define ASSIGN_CONST	2   // ":const"
-#define ASSIGN_NO_DECL	4   // "name = expr" without ":let"/":const"/":final"
-#define ASSIGN_DECL	8   // may declare variable if it does not exist
+#define ASSIGN_FINAL	0x01  // ":final"
+#define ASSIGN_CONST	0x02  // ":const"
+#define ASSIGN_NO_DECL	0x04  // "name = expr" without ":let"/":const"/":final"
+#define ASSIGN_DECL	0x08  // may declare variable if it does not exist
+#define ASSIGN_UNPACK	0x10  // using [a, b] = list
 
 #include "ex_cmds.h"	    // Ex command defines
 #include "spell.h"	    // spell checking stuff
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 02c75c4..15d2c30e 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -6369,6 +6369,17 @@
     {
 	int		instr_count = -1;
 
+	if (var_start[0] == '_' && !eval_isnamec(var_start[1]))
+	{
+	    // Ignore underscore in "[a, _, b] = list".
+	    if (var_count > 0)
+	    {
+		var_start = skipwhite(var_start + 2);
+		continue;
+	    }
+	    emsg(_(e_cannot_use_underscore_here));
+	    goto theend;
+	}
 	vim_free(lhs.lhs_name);
 
 	/*
@@ -6388,11 +6399,6 @@
 	    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)
 	{