summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-02-22 19:39:13 +0000
committerBram Moolenaar <Bram@vim.org>2022-02-22 19:39:13 +0000
commitfe73255c92b6cb54851f82fa32458340b736298d (patch)
treea2b7a346b7178ec3bca0b2ef1fd163fb6b0682c2
parent29a9e6971849b4a9eabf14fee1130d51cecfbaa7 (diff)
downloadvim-git-fe73255c92b6cb54851f82fa32458340b736298d.tar.gz
patch 8.2.4446: Vim9: cannot refer to a global function like a local onev8.2.4446
Problem: Vim9: cannot refer to a global function like a local one. Solution: When g:name is not a variable but a function, use a function reference. (closes #9826)
-rw-r--r--src/testdir/test_vim9_builtin.vim15
-rw-r--r--src/version.c2
-rw-r--r--src/vim9execute.c27
3 files changed, 39 insertions, 5 deletions
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index b91e9f2dc..2c183fd3c 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -427,6 +427,21 @@ def Test_call_call()
call('reverse', [l])
l->assert_equal([1, 2, 3])
+ var lines =<< trim END
+ vim9script
+ def Outer()
+ def g:Inner()
+ g:done = 'Inner'
+ enddef
+ call(g:Inner, [])
+ enddef
+ Outer()
+ assert_equal('Inner', g:done)
+ unlet g:done
+ END
+ v9.CheckScriptSuccess(lines)
+ delfunc g:Inner
+
v9.CheckDefExecAndScriptFailure(['call(123, [2])'], 'E1256: String or function required for argument 1')
v9.CheckDefExecAndScriptFailure(['call(true, [2])'], 'E1256: String or function required for argument 1')
v9.CheckDefAndScriptFailure(['call("reverse", 2)'], ['E1013: Argument 2: type mismatch, expected list<any> but got number', 'E1211: List required for argument 2'])
diff --git a/src/version.c b/src/version.c
index cb6e8e3e8..253cbe809 100644
--- 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 */
/**/
+ 4446,
+/**/
4445,
/**/
4444,
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 3c23ad411..beca9e723 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2333,16 +2333,33 @@ load_namespace_var(ectx_T *ectx, isntype_T isn_type, isn_T *iptr)
if (di == NULL)
{
+ if (isn_type == ISN_LOADG)
+ {
+ ufunc_T *ufunc = find_func(iptr->isn_arg.string, TRUE);
+
+ // g:Something could be a function
+ if (ufunc != NULL)
+ {
+ typval_T *tv = STACK_TV_BOT(0);
+
+ ++ectx->ec_stack.ga_len;
+ tv->v_type = VAR_FUNC;
+ tv->vval.v_string = alloc(STRLEN(iptr->isn_arg.string) + 3);
+ if (tv->vval.v_string == NULL)
+ return FAIL;
+ STRCPY(tv->vval.v_string, "g:");
+ STRCPY(tv->vval.v_string + 2, iptr->isn_arg.string);
+ return OK;
+ }
+ }
SOURCING_LNUM = iptr->isn_lnum;
- if (vim_strchr(iptr->isn_arg.string,
- AUTOLOAD_CHAR) != NULL)
+ if (vim_strchr(iptr->isn_arg.string, AUTOLOAD_CHAR) != NULL)
// no check if the item exists in the script but
// isn't exported, it is too complicated
- semsg(_(e_item_not_found_in_script_str),
- iptr->isn_arg.string);
+ semsg(_(e_item_not_found_in_script_str), iptr->isn_arg.string);
else
semsg(_(e_undefined_variable_char_str),
- namespace, iptr->isn_arg.string);
+ namespace, iptr->isn_arg.string);
return FAIL;
}
else