patch 8.2.4589: cannot index the g: dictionary
Problem: Cannot index the g: dictionary.
Solution: Recognize using "g:[key]". (closes #9969)
diff --git a/src/eval.c b/src/eval.c
index 3f6be18..8d1e4fd 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -929,7 +929,8 @@
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;
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 4066f8d..463d840 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -3523,12 +3523,14 @@
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;
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 37ca2ae..d2d7217 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -1117,6 +1117,14 @@
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
diff --git a/src/version.c b/src/version.c
index 6c59f95..6f86d2b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 4589,
+/**/
4588,
/**/
4587,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index fa5f067..e6c2233 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1000,7 +1000,12 @@
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 @@
// Recognize an assignment if we recognize the variable
// name:
- // "g:var = 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"
+ // "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
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);