From: Hirohito Higashi Date: Mon, 3 Aug 2026 20:02:51 +0000 (+0000) Subject: patch 9.2.0903: Vim9: cannot use an exported function of an autoload import X-Git-Tag: v9.2.0903^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ec4fd2c0e6204334c95f7312b3da156b42bad31;p=thirdparty%2Fvim.git patch 9.2.0903: Vim9: cannot use an exported function of an autoload import Problem: Using an exported function of a script imported with "import autoload" as a value gives E121, unless the script is under an "autoload" directory. Solution: When the name is not a script variable also look for an exported function and push a funcref for it (Hirohito Hirohito). fixes: #20911 closes: #20922 Co-Authored-By: Claude Opus 5 (1M context) Signed-off-by: Hirohito Higashi Signed-off-by: Christian Brabandt --- diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim index 54bbd3f2aa..4c441b1ca3 100644 --- a/src/testdir/test_vim9_import.vim +++ b/src/testdir/test_vim9_import.vim @@ -2843,6 +2843,41 @@ def Test_import_autoload_postponed() &rtp = save_rtp enddef +def Test_import_autoload_func_as_value() + var lines =<< trim END + vim9script + export def Exported(): string + return 'exported' + enddef + END + writefile(lines, 'XimportRelFunc.vim', 'D') + writefile(lines, 'XimportRelFunc2.vim', 'D') + + # Using the exported function as a value, not calling it. + lines =<< trim END + vim9script + import autoload './XimportRelFunc.vim' + def Func() + var Fn: func = XimportRelFunc.Exported + assert_equal('exported', Fn()) + enddef + Func() + END + v9.CheckScriptSuccess(lines) + + # The script is not loaded yet when compiling, thus the name is only + # checked when the function runs. + lines =<< trim END + vim9script + import autoload './XimportRelFunc2.vim' + def Func() + var Fn: func = XimportRelFunc2.NoSuchFunc + enddef + Func() + END + v9.CheckScriptFailure(lines, 'E121: Undefined variable: NoSuchFunc', 1) +enddef + def Test_import_autoload_override() mkdir('Xoverdir/autoload', 'pR') var save_rtp = &rtp diff --git a/src/version.c b/src/version.c index 851013e9e5..2fed34c3a1 100644 --- a/src/version.c +++ b/src/version.c @@ -763,6 +763,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 903, /**/ 902, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index 1c30338eb8..c8790d634a 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -4180,9 +4180,30 @@ exec_instructions(ectx_T *ectx) if (di == NULL) { - SOURCING_LNUM = iptr->isn_lnum; - semsg(_(e_undefined_variable_str), name); - goto on_error; + ufunc_T *ufunc = NULL; + + if (iptr->isn_type == ISN_LOADEXPORT) + { + type_T *type; + + // Not a variable, it can be an exported function + // used as a value. + (void)find_exported(sid, name, &ufunc, &type, + NULL, NULL, FALSE); + } + if (ufunc == NULL) + { + SOURCING_LNUM = iptr->isn_lnum; + semsg(_(e_undefined_variable_str), name); + goto on_error; + } + if (GA_GROW_FAILS(&ectx->ec_stack, 1)) + goto theend; + tv = STACK_TV_BOT(0); + tv->v_lock = 0; + ++ectx->ec_stack.ga_len; + tv->v_type = VAR_FUNC; + tv->vval.v_string = vim_strsave(ufunc->uf_name); } else {