diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-09-23 15:56:50 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-09-23 15:56:50 +0200 |
commit | 81ed4960482f8baabdd7f95b4d5e39744be88ae7 (patch) | |
tree | 53339c1c9e90871169f6da1b8efb3eda6da691df | |
parent | 04bdd573d0a48e789eb92ed2a81e0dd732761391 (diff) | |
download | vim-git-81ed4960482f8baabdd7f95b4d5e39744be88ae7.tar.gz |
patch 8.2.1731: Vim9: cannot use += to append to empty NULL listv8.2.1731
Problem: Vim9: cannot use += to append to empty NULL list.
Solution: Copy the list instead of extending it. (closes #6998)
-rw-r--r-- | src/eval.c | 28 | ||||
-rw-r--r-- | src/testdir/test_vim9_assign.vim | 14 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 40 insertions, 4 deletions
diff --git a/src/eval.c b/src/eval.c index 9b9b7f47c..6c37e70d0 100644 --- 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_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: diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 852db4ad7..4c825e8f6 100644 --- 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 diff --git a/src/version.c b/src/version.c index 655e34919..9e7825a97 100644 --- 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, |