changeset 22365:a4866826cebc v8.2.1731

patch 8.2.1731: Vim9: cannot use += to append to empty NULL list Commit: https://github.com/vim/vim/commit/81ed4960482f8baabdd7f95b4d5e39744be88ae7 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Sep 23 15:56:50 2020 +0200 patch 8.2.1731: Vim9: cannot use += to append to empty NULL list Problem: Vim9: cannot use += to append to empty NULL list. Solution: Copy the list instead of extending it. (closes https://github.com/vim/vim/issues/6998)
author Bram Moolenaar <Bram@vim.org>
date Wed, 23 Sep 2020 16:00:04 +0200
parents 436bae5a7f5b
children 5dd250163338
files src/eval.c src/testdir/test_vim9_assign.vim src/version.c
diffstat 3 files changed, 40 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -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
 		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:
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -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
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1731,
+/**/
     1730,
 /**/
     1729,