]> granicus.if.org Git - vim/commitdiff
patch 8.2.1731: Vim9: cannot use += to append to empty NULL list v8.2.1731
authorBram Moolenaar <Bram@vim.org>
Wed, 23 Sep 2020 13:56:50 +0000 (15:56 +0200)
committerBram Moolenaar <Bram@vim.org>
Wed, 23 Sep 2020 13:56:50 +0000 (15:56 +0200)
Problem:    Vim9: cannot use += to append to empty NULL list.
Solution:   Copy the list instead of extending it. (closes #6998)

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

index 9b9b7f47caa7cc2d97d12cdfa2244de206df71f5..6c37e70d00e85d247e4de442dd76722c71713fe9 100644 (file)
@@ -872,8 +872,7 @@ get_lval(
     while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT))
     {
        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->vval.v_dict != NULL)
+               && !(lp->ll_tv->v_type == VAR_DICT)
                && !(lp->ll_tv->v_type == VAR_BLOB
                                           && lp->ll_tv->vval.v_blob != NULL))
        {
@@ -994,7 +993,20 @@ get_lval(
                }
            }
            lp->ll_list = NULL;
+
+           // a NULL dict is equivalent with an empty dict
+           if (lp->ll_tv->vval.v_dict == NULL)
+           {
+               lp->ll_tv->vval.v_dict = dict_alloc();
+               if (lp->ll_tv->vval.v_dict == NULL)
+               {
+                   clear_tv(&var1);
+                   return NULL;
+               }
+               ++lp->ll_tv->vval.v_dict->dv_refcount;
+           }
            lp->ll_dict = lp->ll_tv->vval.v_dict;
+
            lp->ll_di = dict_find(lp->ll_dict, key, len);
 
            // When assigning to a scope dictionary check that a function and
@@ -1460,8 +1472,16 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
                if (*op != '+' || tv2->v_type != VAR_LIST)
                    break;
                // List += List
-               if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL)
-                   list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+               if (tv2->vval.v_list != NULL)
+               {
+                   if (tv1->vval.v_list == NULL)
+                   {
+                       tv1->vval.v_list = tv2->vval.v_list;
+                       ++tv1->vval.v_list->lv_refcount;
+                   }
+                   else
+                       list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL);
+               }
                return OK;
 
            case VAR_NUMBER:
index 852db4ad777e972ed385f61e97862b0e90296316..4c825e8f69026783a47fc42b415f0b18027ff357 100644 (file)
@@ -223,6 +223,20 @@ def Test_assignment()
   endif
 enddef
 
+def Test_extend_list()
+  let lines =<< trim END
+      vim9script
+      let l: list<number>
+      l += [123]
+      assert_equal([123], l)
+
+      let d: dict<number>
+      d['one'] = 1
+      assert_equal(#{one: 1}, d)
+  END
+  CheckScriptSuccess(lines)
+enddef
+
 def Test_single_letter_vars()
   # single letter variables
   let a: number = 123
index 655e34919a731a2ec40926170aa1ce7251960323..9e7825a97c3369398ef15ebf66963b8e4980ab2a 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1731,
 /**/
     1730,
 /**/