changeset 33718:2fc593290679 v9.0.2091

patch 9.0.2091: Vim9: cannot convert list to string using += Commit: https://github.com/vim/vim/commit/6709816f7807c3ebb062a3124e660def184b739b Author: Yegappan Lakshmanan <yegappan@yahoo.com> Date: Sun Nov 5 10:07:03 2023 +0100 patch 9.0.2091: Vim9: cannot convert list to string using += Problem: Vim9: cannot convert list to string using += (after 9.0.2072) Solution: convert dict index to string later in compile_member() fixes: #13485 closes: #13486 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Sun, 05 Nov 2023 10:15:05 +0100
parents 6e3312a7d33e
children e20d8f3b73f0
files src/testdir/test_vim9_assign.vim src/testdir/test_vim9_disassemble.vim src/version.c src/vim9compile.c
diffstat 4 files changed, 61 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -2992,15 +2992,69 @@ def Test_list_item_assign()
     vim9script
 
     def Foo()
-        var l: list<list<string>> = [['x', 'x', 'x'], ['y', 'y', 'y']]
-        var z: number = 1
-
-        [l[1][2], z] = ['a', 20]
-        assert_equal([['x', 'x', 'x'], ['y', 'y', 'a']], l)
+      var l: list<list<string>> = [['x', 'x', 'x'], ['y', 'y', 'y']]
+      var z: number = 1
+
+      [l[1][2], z] = ['a', 20]
+      assert_equal([['x', 'x', 'x'], ['y', 'y', 'a']], l)
     enddef
     Foo()
   END
   v9.CheckSourceSuccess(lines)
+
+  lines =<< trim END
+    vim9script
+
+    var l: list<list<string>> = [['x', 'x', 'x'], ['y', 'y', 'y']]
+    var z: number = 1
+
+    [l[1][2], z] = ['a', 20]
+    assert_equal([['x', 'x', 'x'], ['y', 'y', 'a']], l)
+  END
+  v9.CheckSourceSuccess(lines)
+enddef
+
+" Test for assigning to a multi-dimensional dict item.
+def Test_dict_item_assign()
+  # This used to fail with the error "E1105: Cannot convert list to string"
+  # (Github issue #13485)
+  var lines =<< trim END
+    vim9script
+    def F()
+      var d: dict<dict<number>> = {a: {b: 0}}
+
+      for group in keys(d)
+        d['a']['b'] += 1
+      endfor
+      assert_equal({a: {b: 1}}, d)
+    enddef
+    F()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # This used to crash Vim
+  lines =<< trim END
+    vim9script
+    def F()
+      var d: dict<dict<number>> = {a: {b: 0}}
+      d['a']['b'] += 1
+      assert_equal({a: {b: 1}}, d)
+    enddef
+    F()
+  END
+  v9.CheckSourceSuccess(lines)
+
+  # Assignment at script level
+  lines =<< trim END
+    vim9script
+    var d: dict<dict<number>> = {a: {b: 0}}
+
+    for group in keys(d)
+      d['a']['b'] += 1
+    endfor
+    assert_equal({a: {b: 1}}, d)
+  END
+  v9.CheckSourceSuccess(lines)
 enddef
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -560,7 +560,6 @@ def Test_disassemble_store_index()
         '\d LOAD $0\_s*' ..
         '\d MEMBER dd\_s*' ..
         '\d\+ USEDICT\_s*' ..
-        '\d\+ 2STRING stack\[-2\]\_s*' ..
         '\d\+ STOREINDEX any\_s*' ..
         '\d\+ RETURN void',
         res)
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2091,
+/**/
     2090,
 /**/
     2089,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -2221,15 +2221,6 @@ compile_load_lhs(
 		return FAIL;
 	}
 
-	if (lhs->lhs_type->tt_type == VAR_DICT && var_start[varlen] == '[')
-	{
-	    // If the lhs is a Dict variable and an item is accessed by "[",
-	    // then need to convert the key into a string.  The top item in the
-	    // type stack is the Dict and the second last item is the key.
-	    if (may_generate_2STRING(-2, FALSE, cctx) == FAIL)
-		return FAIL;
-	}
-
 	// Now we can properly check the type.  The variable is indexed, thus
 	// we need the member type.  For a class or object we don't know the
 	// type yet, it depends on what member is used.