]> granicus.if.org Git - vim/commitdiff
patch 8.2.1135: Vim9: getting a dict member may not work v8.2.1135
authorBram Moolenaar <Bram@vim.org>
Sun, 5 Jul 2020 14:51:26 +0000 (16:51 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 5 Jul 2020 14:51:26 +0000 (16:51 +0200)
Problem:    Vim9: getting a dict member may not work.
Solution:   Clear the dict only after copying the item.

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

index aef1815121a6e40ee11cbad9ae93a75656cb6468..b3906c1b98b7723dc698391b376cd2597d6f9327 100644 (file)
@@ -1128,6 +1128,8 @@ def Test_expr7_dict_vim9script()
   CheckScriptFailure(lines, 'E1069:')
 enddef
 
+let g:oneString = 'one'
+
 def Test_expr_member()
   assert_equal(1, g:dict_one.one)
   let d: dict<number> = g:dict_one
@@ -1135,6 +1137,7 @@ def Test_expr_member()
 
   # getting the one member should clear the dict after getting the item
   assert_equal('one', #{one: 'one'}.one)
+  assert_equal('one', #{one: 'one'}[g:oneString])
 
   call CheckDefFailure(["let x = g:dict_one.#$!"], 'E1002:')
   call CheckDefExecFailure(["let d: dict<any>", "echo d['a']"], 'E716:')
index 8774b2a8d91922485a1b1240accaebad19d9ea69..82e4c6ddcbd91fb241aa4c8deb685243995cca3c 100644 (file)
@@ -754,6 +754,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1135,
 /**/
     1134,
 /**/
index 47e072e5492e0728e71b2d0cc93e4777c989f326..7afa3fc5ec9dad2251a588b99cb8a84986b6b0bf 100644 (file)
@@ -2166,6 +2166,7 @@ call_def_function(
                    dict_T      *dict;
                    char_u      *key;
                    dictitem_T  *di;
+                   typval_T    temp_tv;
 
                    // dict member: dict is at stack-2, key at stack-1
                    tv = STACK_TV_BOT(-2);
@@ -2181,10 +2182,14 @@ call_def_function(
                        semsg(_(e_dictkey), key);
                        goto failed;
                    }
-                   --ectx.ec_stack.ga_len;
                    clear_tv(tv);
-                   clear_tv(STACK_TV_BOT(-1));
-                   copy_tv(&di->di_tv, STACK_TV_BOT(-1));
+                   --ectx.ec_stack.ga_len;
+                   // Clear the dict after getting the item, to avoid that it
+                   // make the item invalid.
+                   tv = STACK_TV_BOT(-1);
+                   temp_tv = *tv;
+                   copy_tv(&di->di_tv, tv);
+                   clear_tv(&temp_tv);
                }
                break;