patch 9.2.0903: Vim9: cannot use an exported function of an autoload import
Commit:
https://github.com/vim/vim/commit/1ec4fd2c0e6204334c95f7312b3da156b42bad31
Author: Hirohito Higashi <
h.eas...@gmail.com>
Date: Mon Aug 3 20:02:51 2026 +0000
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) <
nor...@anthropic.com>
Signed-off-by: Hirohito Higashi <
h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index 54bbd3f2a..4c441b1ca 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 851013e9e..2fed34c3a 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 1c30338eb..c8790d634 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
{