Skip to content

Commit

Permalink
patch 8.2.3064: Vim9: in script cannot set item in uninitialized list
Browse files Browse the repository at this point in the history
Problem:    Vim9: in script cannot set item in uninitialized list.
Solution:   When a list is NULL allocate an empty one. (closes vim#8461)
  • Loading branch information
brammool committed Jun 27, 2021
1 parent 65aee0b commit e65081d
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 23 deletions.
33 changes: 25 additions & 8 deletions src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -932,15 +932,22 @@ get_lval(
semsg(_(e_dot_can_only_be_used_on_dictionary_str), name);
return NULL;
}
if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL)
&& !(lp->ll_tv->v_type == VAR_DICT)
&& !(lp->ll_tv->v_type == VAR_BLOB
&& lp->ll_tv->vval.v_blob != NULL))
if (lp->ll_tv->v_type != VAR_LIST
&& lp->ll_tv->v_type != VAR_DICT
&& lp->ll_tv->v_type != VAR_BLOB)
{
if (!quiet)
emsg(_("E689: Can only index a List, Dictionary or Blob"));
return NULL;
}

// a NULL list/blob works like an empty list/blob, allocate one now.
if (lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list == NULL)
rettv_list_alloc(lp->ll_tv);
else if (lp->ll_tv->v_type == VAR_BLOB
&& lp->ll_tv->vval.v_blob == NULL)
rettv_blob_alloc(lp->ll_tv);

if (lp->ll_range)
{
if (!quiet)
Expand Down Expand Up @@ -1201,10 +1208,20 @@ get_lval(
lp->ll_li = list_find_index(lp->ll_list, &lp->ll_n1);
if (lp->ll_li == NULL)
{
clear_tv(&var2);
if (!quiet)
semsg(_(e_listidx), lp->ll_n1);
return NULL;
// Vim9: Allow for adding an item at the end.
if (in_vim9script() && lp->ll_n1 == lp->ll_list->lv_len
&& lp->ll_list->lv_lock == 0)
{
list_append_number(lp->ll_list, 0);
lp->ll_li = list_find_index(lp->ll_list, &lp->ll_n1);
}
if (lp->ll_li == NULL)
{
clear_tv(&var2);
if (!quiet)
semsg(_(e_listidx), lp->ll_n1);
return NULL;
}
}

if (lp->ll_valtype != NULL)
Expand Down
39 changes: 24 additions & 15 deletions src/testdir/test_vim9_assign.vim
Original file line number Diff line number Diff line change
Expand Up @@ -1102,21 +1102,30 @@ def Test_assignment_failure()
enddef

def Test_assign_list()
var l: list<string> = []
l[0] = 'value'
assert_equal('value', l[0])

l[1] = 'asdf'
assert_equal('value', l[0])
assert_equal('asdf', l[1])
assert_equal('asdf', l[-1])
assert_equal('value', l[-2])

var nrl: list<number> = []
for i in range(5)
nrl[i] = i
endfor
assert_equal([0, 1, 2, 3, 4], nrl)
var lines =<< trim END
var l: list<string> = []
l[0] = 'value'
assert_equal('value', l[0])

l[1] = 'asdf'
assert_equal('value', l[0])
assert_equal('asdf', l[1])
assert_equal('asdf', l[-1])
assert_equal('value', l[-2])

var nrl: list<number> = []
for i in range(5)
nrl[i] = i
endfor
assert_equal([0, 1, 2, 3, 4], nrl)

var ul: list<any>
ul[0] = 1
ul[1] = 2
ul[2] = 3
assert_equal([1, 2, 3], ul)
END
CheckDefAndScriptSuccess(lines)

CheckDefFailure(["var l: list<number> = ['', true]"], 'E1012: Type mismatch; expected list<number> but got list<any>', 1)
CheckDefFailure(["var l: list<list<number>> = [['', true]]"], 'E1012: Type mismatch; expected list<list<number>> but got list<list<any>>', 1)
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
3064,
/**/
3063,
/**/
Expand Down

0 comments on commit e65081d

Please sign in to comment.