Patch 8.2.3064
Problem: Vim9: in script cannot set item in uninitialized list.
Solution: When a list is NULL allocate an empty one. (closes #8461)
Files: src/eval.c, src/testdir/test_vim9_assign.vim
*** ../vim-8.2.3063/src/eval.c 2021-06-26 15:00:55.881276189 +0200
--- src/eval.c 2021-06-27 15:02:10.281185185 +0200
***************
*** 932,946 ****
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 (!quiet)
emsg(_("E689: Can only index a List, Dictionary or Blob"));
return NULL;
}
if (lp->ll_range)
{
if (!quiet)
--- 932,953 ----
semsg(_(e_dot_can_only_be_used_on_dictionary_str), name);
return 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)
***************
*** 1201,1210 ****
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)
--- 1208,1227 ----
lp->ll_li = list_find_index(lp->ll_list, &lp->ll_n1);
if (lp->ll_li == 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)
*** ../vim-8.2.3063/src/testdir/test_vim9_assign.vim 2021-06-26 15:00:55.881276189 +0200
--- src/testdir/test_vim9_assign.vim 2021-06-27 14:59:35.473507986 +0200
***************
*** 1102,1122 ****
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)
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)
--- 1102,1131 ----
enddef
def Test_assign_list()
! 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)
*** ../vim-8.2.3063/src/version.c 2021-06-27 14:08:17.568112117 +0200
--- src/version.c 2021-06-27 15:02:43.309049970 +0200
***************
*** 757,758 ****
--- 757,760 ----
{ /* Add new patch number below this line */
+ /**/
+ 3064,
/**/
--
Just remember...if the world didn't suck, we'd all fall off.
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///