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:
1 parent
415a3b841b
commit
e5826687d1
3 files changed
+24
-8
No files matched your search
@@ -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()
|
||||
|
||||
@@ -743,6 +743,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1242,
|
||||
/**/
|
||||
1241,
|
||||
/**/
|
||||
|
||||
+8
-8
@@ -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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user