changeset 25028:faa3de7aed8b v8.2.3051

patch 8.2.3051: Vim9: for loop with one list variable does not work Commit: https://github.com/vim/vim/commit/444d878324525787e55185ce3c3e29a3de9b700a Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jun 26 12:40:56 2021 +0200 patch 8.2.3051: Vim9: for loop with one list variable does not work Problem: Vim9: for loop with one list variable does not work. Solution: Use a separate flag for unpacking a list. (closes https://github.com/vim/vim/issues/8452)
author Bram Moolenaar <Bram@vim.org>
date Sat, 26 Jun 2021 12:45:03 +0200
parents ea3486f096df
children 61af9ea403ab
files src/testdir/test_vim9_script.vim src/version.c src/vim9compile.c
diffstat 3 files changed, 16 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_script.vim
+++ b/src/testdir/test_vim9_script.vim
@@ -2385,6 +2385,13 @@ def Test_for_loop()
       endfor
       assert_equal('1a2b', res)
 
+      # unpack with one var
+      var reslist = []
+      for [x] in [['aaa'], ['bbb']]
+        reslist->add(x)
+      endfor
+      assert_equal(['aaa', 'bbb'], reslist)
+
       # loop over string
       res = ''
       for c in 'aéc̀d'
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3051,
+/**/
     3050,
 /**/
     3049,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -7731,6 +7731,7 @@ compile_for(char_u *arg_start, cctx_T *c
     char_u	*p;
     char_u	*wp;
     int		var_count = 0;
+    int		var_list = FALSE;
     int		semicolon = FALSE;
     size_t	varlen;
     garray_T	*stack = &cctx->ctx_type_stack;
@@ -7747,6 +7748,8 @@ compile_for(char_u *arg_start, cctx_T *c
 	return NULL;
     if (var_count == 0)
 	var_count = 1;
+    else
+	var_list = TRUE;  // can also be a list of one variable
 
     // consume "in"
     wp = p;
@@ -7811,7 +7814,7 @@ compile_for(char_u *arg_start, cctx_T *c
     else if (vartype->tt_type == VAR_LIST
 				     && vartype->tt_member->tt_type != VAR_ANY)
     {
-	if (var_count == 1)
+	if (!var_list)
 	    item_type = vartype->tt_member;
 	else if (vartype->tt_member->tt_type == VAR_LIST
 		      && vartype->tt_member->tt_member->tt_type != VAR_ANY)
@@ -7828,7 +7831,7 @@ compile_for(char_u *arg_start, cctx_T *c
     generate_FOR(cctx, loop_lvar->lv_idx);
 
     arg = arg_start;
-    if (var_count > 1)
+    if (var_list)
     {
 	generate_UNPACK(cctx, var_count, semicolon);
 	arg = skipwhite(arg + 1);	// skip white after '['
@@ -7899,12 +7902,12 @@ compile_for(char_u *arg_start, cctx_T *c
 	    }
 
 	    // Reserve a variable to store "var".
-	    where.wt_index = var_count > 1 ? idx + 1 : 0;
+	    where.wt_index = var_list ? idx + 1 : 0;
 	    where.wt_variable = TRUE;
 	    if (lhs_type == &t_any)
 		lhs_type = item_type;
 	    else if (item_type != &t_unknown
-		       && !(var_count > 1 && item_type == &t_any)
+		       && !(var_list && item_type == &t_any)
 		       && check_type(lhs_type, item_type, TRUE, where) == FAIL)
 		goto failed;
 	    var_lvar = reserve_local(cctx, arg, varlen, TRUE, lhs_type);