changeset 28129:dd2ed5345f20 v8.2.4589

patch 8.2.4589: cannot index the g: dictionary Commit: https://github.com/vim/vim/commit/2e17fef225a58f478dc24ab1aaa20390c9abce57 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Mar 18 19:44:48 2022 +0000 patch 8.2.4589: cannot index the g: dictionary Problem: Cannot index the g: dictionary. Solution: Recognize using "g:[key]". (closes https://github.com/vim/vim/issues/9969)
author Bram Moolenaar <Bram@vim.org>
date Fri, 18 Mar 2022 20:45:04 +0100
parents afa443a6179a
children f7483c7afd6c
files src/eval.c src/ex_docmd.c src/testdir/test_vim9_assign.vim src/version.c src/vim9compile.c
diffstat 5 files changed, 28 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/eval.c
+++ b/src/eval.c
@@ -929,7 +929,8 @@ get_lval(
 	if (vim9script)
 	{
 	    // "a: type" is declaring variable "a" with a type, not "a:".
-	    if (p == name + 2 && p[-1] == ':')
+	    // However, "g:[key]" is indexing a dictionary.
+	    if (p == name + 2 && p[-1] == ':' && *p != '[')
 	    {
 		--p;
 		lp->ll_name_end = p;
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3523,12 +3523,14 @@ find_ex_command(
 		return eap->cmd;
 	    }
 
-	    if (p != eap->cmd && (
+	    if ((p != eap->cmd && (
 			    // "varname[]" is an expression.
 			    *p == '['
 			    // "varname.key" is an expression.
-			 || (*p == '.' && (ASCII_ISALPHA(p[1])
-							     || p[1] == '_'))))
+			 || (*p == '.'
+				     && (ASCII_ISALPHA(p[1]) || p[1] == '_'))))
+			// g:[key] is an expression
+		    || STRNCMP(eap->cmd, "g:[", 3) == 0)
 	    {
 		char_u	*after = eap->cmd;
 
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -1117,6 +1117,14 @@ def Test_assignment_dict()
   v9.CheckDefAndScriptSuccess(lines)
 
   lines =<< trim END
+    var key = 'foo'
+    g:[key] = 'value'
+    assert_equal('value', g:foo)
+    unlet g:foo
+  END
+  v9.CheckDefAndScriptSuccess(lines)
+
+  lines =<< trim END
     var dd = {one: 1}
     dd.one) = 2
   END
--- 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 */
 /**/
+    4589,
+/**/
     4588,
 /**/
     4587,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1000,7 +1000,12 @@ generate_loadvar(
 	    break;
 	case dest_global:
 	    if (vim_strchr(name, AUTOLOAD_CHAR) == NULL)
-		generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
+	    {
+		if (name[2] == NUL)
+		    generate_instr_type(cctx, ISN_LOADGDICT, &t_dict_any);
+		else
+		    generate_LOAD(cctx, ISN_LOADG, 0, name + 2, type);
+	    }
 	    else
 		generate_LOAD(cctx, ISN_LOADAUTO, 0, name, type);
 	    break;
@@ -2413,17 +2418,19 @@ may_compile_assignment(exarg_T *eap, cha
 
 	    // Recognize an assignment if we recognize the variable
 	    // name:
+	    // "&opt = expr"
+	    // "$ENV = expr"
+	    // "@r = expr"
 	    // "g:var = expr"
+	    // "g:[key] = expr"
 	    // "local = expr"  where "local" is a local var.
 	    // "script = expr"  where "script" is a script-local var.
 	    // "import = expr"  where "import" is an imported var
-	    // "&opt = expr"
-	    // "$ENV = expr"
-	    // "@r = expr"
 	    if (*eap->cmd == '&'
 		    || *eap->cmd == '$'
 		    || *eap->cmd == '@'
 		    || ((len) > 2 && eap->cmd[1] == ':')
+		    || STRNCMP(eap->cmd, "g:[", 3) == 0
 		    || variable_exists(eap->cmd, len, cctx))
 	    {
 		*line = compile_assignment(eap->cmd, eap, CMD_SIZE, cctx);