patch 9.2.1242: Vim9: list instead of tuple for rest of tuple in a :for loop

Problem:  Vim9: In a compiled function, when unpacking a tuple in a :for
          loop, the variable after ";" gets a list with the remaining
          items instead of a tuple.
Solution: Create a tuple with the remaining items (Yegappan Lakshmanan).

The help says that the variable after ";" gets a tuple, this was already
the case when not in a compiled function.

fixes:  #21587
closes: #21588

Assisted-by: Claude Code (Claude Opus 5.5)
Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan authored and Christian Brabandt committed 2026-10-26 10:30:20 +00:00
1 parent 415a3b841b
commit e5826687d1
3 files changed
+24 -8

No files matched your search

+14
View File
@@ -787,6 +787,20 @@ func Test_multi_assign_from_tuple()
call v9.CheckSourceFailure(lines, 'E1093: Expected 2 items but got 0')
endfunc
" Test for the value of the variable after ";" when unpacking a tuple in a
" :for loop. It must be a tuple, also in a compiled function.
def Test_tuple_for_unpack_rest_is_tuple()
var lines =<< trim END
var r = []
for [a; b] in ((1, 2, 3), (4,))
assert_equal(v:t_tuple, type(b))
r->add(b)
endfor
assert_equal([(2, 3), ()], r)
END
v9.CheckSourceDefAndScriptSuccess(lines)
enddef
" Test for performing an arithmetic operation on multiple variables using
" items from a tuple
func Test_multi_arithmetic_op_from_tuple()
+2
View File
@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1242,
/**/
1241,
/**/
+8 -8
View File
@@ -3583,26 +3583,26 @@ exec_unpack_tuple(ectx_T *ectx, isn_T *iptr, typval_T *tv)
return EXEC_DONE;
ectx->ec_stack.ga_len += count - 1;
// Variable after semicolon gets a list with the remaining
// Variable after semicolon gets a tuple with the remaining
// items.
if (semicolon)
{
list_T *rem_list =
list_alloc_with_items(TUPLE_LEN(tuple) - count + 1);
tuple_T *rem_tuple =
tuple_alloc_with_items(TUPLE_LEN(tuple) - count + 1);
if (rem_list == NULL)
if (rem_tuple == NULL)
return EXEC_DONE;
tv = STACK_TV_BOT(-count);
tv->v_type = VAR_LIST;
tv->vval.v_list = rem_list;
++rem_list->lv_refcount;
tv->v_type = VAR_TUPLE;
tv->vval.v_tuple = rem_tuple;
++rem_tuple->tv_refcount;
tv->v_lock = 0;
for (i = count - 1; i < TUPLE_LEN(tuple); ++i)
{
typval_T tvcopy;
copy_tv(TUPLE_ITEM(tuple, i), &tvcopy);
list_set_item(rem_list, i - (count - 1), &tvcopy);
tuple_set_item(rem_tuple, i - (count - 1), &tvcopy);
}
--count;
}