]> granicus.if.org Git - vim/commitdiff
patch 8.2.1127: Vim9: getting a dict member may not work v8.2.1127
authorBram Moolenaar <Bram@vim.org>
Sat, 4 Jul 2020 17:19:43 +0000 (19:19 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 4 Jul 2020 17:19:43 +0000 (19:19 +0200)
Problem:    Vim9: getting a dict member may not work.
Solution:   Clear the dict only after copying the item. (closes #6390)

src/testdir/test_vim9_expr.vim
src/version.c
src/vim9execute.c

index a604de2b0b06c6ac244d9291b288117cda0f2507..3bf578059f1944c53047776f4fd1f1c6e3c03ce3 100644 (file)
@@ -1133,6 +1133,9 @@ def Test_expr_member()
   let d: dict<number> = g:dict_one
   assert_equal(1, d['one'])
 
+  # getting the one member should clear the dict after getting the item
+  assert_equal('one', #{one: 'one'}.one)
+
   call CheckDefFailure(["let x = g:dict_one.#$!"], 'E1002:')
   call CheckDefExecFailure(["let d: dict<any>", "echo d['a']"], 'E716:')
   call CheckDefExecFailure(["let d: dict<number>", "d = g:list_empty"], 'E1029: Expected dict but got list')
index d1607ae15d5e32254b41762bd2e717f608f77ffa..b406a6957768ad0d56a01b130dde1faa85bfcfea 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1127,
 /**/
     1126,
 /**/
index b4acb35c10453bcd7631284ada2e88ae1210713c..bcacaabaa00a8d84094c9d63af281429b3c23144 100644 (file)
@@ -2188,6 +2188,7 @@ call_def_function(
                {
                    dict_T      *dict;
                    dictitem_T  *di;
+                   typval_T    temp_tv;
 
                    tv = STACK_TV_BOT(-1);
                    if (tv->v_type != VAR_DICT || tv->vval.v_dict == NULL)
@@ -2203,8 +2204,11 @@ call_def_function(
                        semsg(_(e_dictkey), iptr->isn_arg.string);
                        goto failed;
                    }
-                   clear_tv(tv);
+                   // Clear the dict after getting the item, to avoid that it
+                   // make the item invalid.
+                   temp_tv = *tv;
                    copy_tv(&di->di_tv, tv);
+                   clear_tv(&temp_tv);
                }
                break;