# HG changeset patch # User Bram Moolenaar # Date 1645559104 -3600 # Node ID 5ce69c07a106904cb9f542a4a3818faac2dded31 # Parent a93a7405f2e231db482dcf6bce17f2f6140ce6d5 patch 8.2.4446: Vim9: cannot refer to a global function like a local one Commit: https://github.com/vim/vim/commit/fe73255c92b6cb54851f82fa32458340b736298d Author: Bram Moolenaar Date: Tue Feb 22 19:39:13 2022 +0000 patch 8.2.4446: Vim9: cannot refer to a global function like a local one 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) diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim --- 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 but got number', 'E1211: List required for argument 2']) diff --git a/src/version.c b/src/version.c --- 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 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2333,16 +2333,33 @@ load_namespace_var(ectx_T *ectx, isntype 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