changeset 27205:6c177a9b436e v8.2.4131

patch 8.2.4131: Vim9: calling function in autoload import does not work Commit: https://github.com/vim/vim/commit/cbbc48f64b9cfd88720dc94b0578a3726f725178 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Jan 18 12:58:28 2022 +0000 patch 8.2.4131: Vim9: calling function in autoload import does not work Problem: Vim9: calling function in autoload import does not work in a :def function. Solution: When a variable is not found and a PCALL follows use a funcref. (closes #9550)
author Bram Moolenaar <Bram@vim.org>
date Tue, 18 Jan 2022 14:00:05 +0100
parents 93806718f805
children db4583616f61
files src/testdir/test_vim9_import.vim src/version.c src/vim9execute.c
diffstat 3 files changed, 45 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -1264,6 +1264,10 @@ def Test_vim9script_autoload_call()
   var lines =<< trim END
      vim9script autoload
 
+     export def RetArg(arg: string): string
+       return arg
+     enddef
+
      export def Getother()
        g:result = 'other'
      enddef
@@ -1273,6 +1277,13 @@ def Test_vim9script_autoload_call()
   lines =<< trim END
       vim9script
       import autoload 'another.vim'
+
+      # compile this before 'another.vim' is loaded
+      def CallAnother()
+        assert_equal('foo', 'foo'->another.RetArg())
+      enddef
+      CallAnother()
+
       call another.Getother()
       assert_equal('other', g:result)
   END
--- 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 */
 /**/
+    4131,
+/**/
     4130,
 /**/
     4129,
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -2200,10 +2200,12 @@ exec_instructions(ectx_T *ectx)
 	    case ISN_LOADW:
 	    case ISN_LOADT:
 		{
-		    dictitem_T *di = NULL;
-		    hashtab_T *ht = NULL;
-		    char namespace;
-
+		    dictitem_T	*di = NULL;
+		    hashtab_T	*ht = NULL;
+		    char	namespace;
+
+		    if (GA_GROW_FAILS(&ectx->ec_stack, 1))
+			goto theend;
 		    switch (iptr->isn_type)
 		    {
 			case ISN_LOADG:
@@ -2227,14 +2229,38 @@ exec_instructions(ectx_T *ectx)
 		    }
 		    di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE);
 
-		    if (di == NULL && ht == get_globvar_ht())
+		    if (di == NULL && ht == get_globvar_ht()
+					    && vim_strchr(iptr->isn_arg.string,
+							AUTOLOAD_CHAR) != NULL)
 		    {
-			// may need to load autoload script
+			// Global variable has an autoload name, may still need
+			// to load the script.
 			if (script_autoload(iptr->isn_arg.string, FALSE))
 			    di = find_var_in_ht(ht, 0,
 						   iptr->isn_arg.string, TRUE);
 			if (did_emsg)
 			    goto on_error;
+			if (di == NULL)
+			{
+			    isn_T   *next = &ectx->ec_instr[ectx->ec_iidx];
+
+			    // When compiling "script.Func()" when "script" is
+			    // an autoload import then this results in
+			    // "LOADG script#Func" because we don't know if it
+			    // is a funcref variable or a function name.  In
+			    // that case a PCALL follows, push the function
+			    // name instead.
+			    if (next->isn_type == ISN_PCALL)
+			    {
+				tv = STACK_TV_BOT(0);
+				tv->v_type = VAR_FUNC;
+				tv->v_lock = 0;
+				tv->vval.v_string =
+					     vim_strsave(iptr->isn_arg.string);
+				++ectx->ec_stack.ga_len;
+				break;
+			    }
+			}
 		    }
 
 		    if (di == NULL)
@@ -2246,8 +2272,6 @@ exec_instructions(ectx_T *ectx)
 		    }
 		    else
 		    {
-			if (GA_GROW_FAILS(&ectx->ec_stack, 1))
-			    goto theend;
 			copy_tv(&di->di_tv, STACK_TV_BOT(0));
 			++ectx->ec_stack.ga_len;
 		    }