]> granicus.if.org Git - vim/commitdiff
patch 8.2.3064: Vim9: in script cannot set item in uninitialized list v8.2.3064
authorBram Moolenaar <Bram@vim.org>
Sun, 27 Jun 2021 13:04:05 +0000 (15:04 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 27 Jun 2021 13:04:05 +0000 (15:04 +0200)
Problem:    Vim9: in script cannot set item in uninitialized list.
Solution:   When a list is NULL allocate an empty one. (closes #8461)

src/eval.c
src/testdir/test_vim9_assign.vim
src/version.c

index 7704d46e983e82dc3e039290e9ab419e7b860061..7990c23f0045dc4d3e078f391e5d81640c77b2a9 100644 (file)
@@ -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)
@@ -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)
index 230ddc50c601d1ba8ff2fe12f0cfaac18b07a12c..86f890ea09012ed0b77969332983694313aea740 100644 (file)
@@ -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)
index 1238a4976b520bbddd79b67d192a7083a714b7e8..12f6648195c1b46a2264677c31fb1fce5b5977f2 100644 (file)
@@ -755,6 +755,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3064,
 /**/
     3063,
 /**/