changeset 20140:39a18a0df429 v8.2.0625

patch 8.2.0625: Vim9: confusing error when calling unknown function Commit: https://github.com/vim/vim/commit/1df8b3fb04ce8732a0be680273c95eb4e9f5e85d Author: Bram Moolenaar <Bram@vim.org> Date: Thu Apr 23 18:13:23 2020 +0200 patch 8.2.0625: Vim9: confusing error when calling unknown function Problem: Vim9: confusing error when calling unknown function. Solution: Give error while compiling.
author Bram Moolenaar <Bram@vim.org>
date Thu, 23 Apr 2020 18:15:04 +0200
parents 92f2b807c515
children 3be7dea7ddcc
files src/testdir/test_vim9_func.vim src/version.c src/vim9compile.c src/vim9execute.c
diffstat 4 files changed, 40 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -193,10 +193,23 @@ def Test_using_var_as_arg()
 enddef
 
 def Test_call_func_defined_later()
-  call assert_equal('one', DefinedLater('one'))
+  call assert_equal('one', g:DefinedLater('one'))
   call assert_fails('call NotDefined("one")', 'E117:')
 enddef
 
+func DefinedLater(arg)
+  return a:arg
+endfunc
+
+def Test_call_funcref()
+  assert_equal(3, g:SomeFunc('abc'))
+  assert_fails('NotAFunc()', 'E117:')
+  assert_fails('g:NotAFunc()', 'E117:')
+enddef
+
+let SomeFunc = function('len')
+let NotAFunc = 'text'
+
 def CombineFuncrefTypes()
   " same arguments, different return type
   let Ref1: func(bool): string
@@ -217,12 +230,8 @@ def CombineFuncrefTypes()
   Refb3 = g:cond ? Refb1 : Refb2
 enddef
 
-func DefinedLater(arg)
-  return a:arg
-endfunc
-
 def FuncWithForwardCall()
-  return DefinedEvenLater("yes")
+  return g:DefinedEvenLater("yes")
 enddef
 
 def DefinedEvenLater(arg: string): string
@@ -372,9 +381,9 @@ def Test_redef_failure()
   so Xdef
   call delete('Xdef')
 
-  call assert_equal(0, Func0())
-  call assert_equal('Func1', Func1())
-  call assert_equal('Func2', Func2())
+  call assert_equal(0, g:Func0())
+  call assert_equal('Func1', g:Func1())
+  call assert_equal('Func2', g:Func2())
 
   delfunc! Func0
   delfunc! Func1
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    625,
+/**/
     624,
 /**/
     623,
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -2463,8 +2463,12 @@ compile_call(char_u **arg, size_t varlen
 	goto theend;
     }
 
-    // The function may be defined only later.  Need to figure out at runtime.
-    res = generate_UCALL(cctx, name, argcount);
+    // A global function may be defined only later.  Need to figure out at
+    // runtime.
+    if (STRNCMP(namebuf, "g:", 2) == 0)
+	res = generate_UCALL(cctx, name, argcount);
+    else
+	semsg(_(e_unknownfunc), namebuf);
 
 theend:
     vim_free(tofree);
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -460,13 +460,20 @@ call_eval_func(char_u *name, int argcoun
     if (call_by_name(name, argcount, ectx, iptr) == FAIL
 					  && called_emsg == called_emsg_before)
     {
-	// "name" may be a variable that is a funcref or partial
-	//    if find variable
-	//      call_partial()
-	//    else
-	//      semsg(_(e_unknownfunc), name);
-	emsg("call_eval_func(partial) not implemented yet");
-	return FAIL;
+	dictitem_T	*v;
+
+	v = find_var(name, NULL, FALSE);
+	if (v == NULL)
+	{
+	    semsg(_(e_unknownfunc), name);
+	    return FAIL;
+	}
+	if (v->di_tv.v_type != VAR_PARTIAL && v->di_tv.v_type != VAR_FUNC)
+	{
+	    semsg(_(e_unknownfunc), name);
+	    return FAIL;
+	}
+	return call_partial(&v->di_tv, argcount, ectx);
     }
     return OK;
 }