0
0
mirror of https://github.com/vim/vim.git synced 2025-09-27 04:14:06 -04:00

patch 8.2.3064: Vim9: in script cannot set item in uninitialized list

Problem:    Vim9: in script cannot set item in uninitialized list.
Solution:   When a list is NULL allocate an empty one. (closes #8461)
This commit is contained in:
Bram Moolenaar
2021-06-27 15:04:05 +02:00
parent 65aee0b714
commit e65081d1b5
3 changed files with 49 additions and 21 deletions

View File

@@ -932,15 +932,22 @@ get_lval(
semsg(_(e_dot_can_only_be_used_on_dictionary_str), name); semsg(_(e_dot_can_only_be_used_on_dictionary_str), name);
return NULL; return NULL;
} }
if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) if (lp->ll_tv->v_type != VAR_LIST
&& !(lp->ll_tv->v_type == VAR_DICT) && lp->ll_tv->v_type != VAR_DICT
&& !(lp->ll_tv->v_type == VAR_BLOB && lp->ll_tv->v_type != VAR_BLOB)
&& lp->ll_tv->vval.v_blob != NULL))
{ {
if (!quiet) if (!quiet)
emsg(_("E689: Can only index a List, Dictionary or Blob")); emsg(_("E689: Can only index a List, Dictionary or Blob"));
return NULL; 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 (lp->ll_range)
{ {
if (!quiet) if (!quiet)
@@ -1201,10 +1208,20 @@ get_lval(
lp->ll_li = list_find_index(lp->ll_list, &lp->ll_n1); lp->ll_li = list_find_index(lp->ll_list, &lp->ll_n1);
if (lp->ll_li == NULL) if (lp->ll_li == NULL)
{ {
clear_tv(&var2); // Vim9: Allow for adding an item at the end.
if (!quiet) if (in_vim9script() && lp->ll_n1 == lp->ll_list->lv_len
semsg(_(e_listidx), lp->ll_n1); && lp->ll_list->lv_lock == 0)
return NULL; {
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) if (lp->ll_valtype != NULL)

View File

@@ -1102,21 +1102,30 @@ def Test_assignment_failure()
enddef enddef
def Test_assign_list() def Test_assign_list()
var l: list<string> = [] var lines =<< trim END
l[0] = 'value' var l: list<string> = []
assert_equal('value', l[0]) l[0] = 'value'
assert_equal('value', l[0])
l[1] = 'asdf' l[1] = 'asdf'
assert_equal('value', l[0]) assert_equal('value', l[0])
assert_equal('asdf', l[1]) assert_equal('asdf', l[1])
assert_equal('asdf', l[-1]) assert_equal('asdf', l[-1])
assert_equal('value', l[-2]) assert_equal('value', l[-2])
var nrl: list<number> = [] var nrl: list<number> = []
for i in range(5) for i in range(5)
nrl[i] = i nrl[i] = i
endfor endfor
assert_equal([0, 1, 2, 3, 4], nrl) 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<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) CheckDefFailure(["var l: list<list<number>> = [['', true]]"], 'E1012: Type mismatch; expected list<list<number>> but got list<list<any>>', 1)

View File

@@ -755,6 +755,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
3064,
/**/ /**/
3063, 3063,
/**/ /**/