summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-04-12 14:39:53 +0200
committerBram Moolenaar <Bram@vim.org>2020-04-12 14:39:53 +0200
commit99aaf0ce7cc23b0e759eab2369e266cdc8d46af8 (patch)
tree113e7b9337ac331536b843e8e03947f153e88108
parent1363a30cef382b912bf092969e040333c5c293c6 (diff)
downloadvim-git-99aaf0ce7cc23b0e759eab2369e266cdc8d46af8.tar.gz
patch 8.2.0552: Vim9: some errors not covered by testsv8.2.0552
Problem: Vim9: some errors not covered by tests. Solution: Add more tests. Check Funcref argument types.
-rw-r--r--src/testdir/test_vim9_func.vim21
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c42
3 files changed, 60 insertions, 5 deletions
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index 57ecf51ff..a40ac3e99 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -96,6 +96,7 @@ def Test_call_default_args()
assert_fails('call MyDefaultArgs("one", "two")', 'E118:')
call CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef'], 'E1001:')
+ call CheckScriptFailure(['def Func(arg: number = "text")', 'enddef'], 'E1013: argument 1: type mismatch, expected number but got string')
enddef
func Test_call_default_args_from_func()
@@ -196,6 +197,26 @@ def Test_call_func_defined_later()
call assert_fails('call NotDefined("one")', 'E117:')
enddef
+def CombineFuncrefTypes()
+ " same arguments, different return type
+ let Ref1: func(bool): string
+ let Ref2: func(bool): number
+ let Ref3: func(bool): any
+ Ref3 = g:cond ? Ref1 : Ref2
+
+ " different number of arguments
+ let Refa1: func(bool): number
+ let Refa2: func(bool, number): number
+ let Refa3: func: number
+ Refa3 = g:cond ? Refa1 : Refa2
+
+ " different argument types
+ let Refb1: func(bool, string): number
+ let Refb2: func(string, number): number
+ let Refb3: func(any, any): number
+ Refb3 = g:cond ? Refb1 : Refb2
+enddef
+
func DefinedLater(arg)
return a:arg
endfunc
diff --git a/src/version.c b/src/version.c
index 4959ab712..2985dd0b0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -739,6 +739,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 552,
+/**/
551,
/**/
550,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 33c4a6cdf..772e29f35 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -1746,6 +1746,8 @@ parse_type(char_u **arg, garray_T *type_gap)
static int
equal_type(type_T *type1, type_T *type2)
{
+ int i;
+
if (type1->tt_type != type2->tt_type)
return FALSE;
switch (type1->tt_type)
@@ -1767,9 +1769,16 @@ equal_type(type_T *type1, type_T *type2)
return equal_type(type1->tt_member, type2->tt_member);
case VAR_FUNC:
case VAR_PARTIAL:
- // TODO; check argument types.
- return equal_type(type1->tt_member, type2->tt_member)
- && type1->tt_argcount == type2->tt_argcount;
+ if (!equal_type(type1->tt_member, type2->tt_member)
+ || type1->tt_argcount != type2->tt_argcount)
+ return FALSE;
+ if (type1->tt_argcount < 0
+ || type1->tt_args == NULL || type2->tt_args == NULL)
+ return TRUE;
+ for (i = 0; i < type1->tt_argcount; ++i)
+ if (!equal_type(type1->tt_args[i], type2->tt_args[i]))
+ return FALSE;
+ return TRUE;
}
return TRUE;
}
@@ -1800,8 +1809,31 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
*dest = get_dict_type(common, type_gap);
return;
}
- // TODO: VAR_FUNC and VAR_PARTIAL
- *dest = type1;
+ if (type1->tt_type == VAR_FUNC)
+ {
+ type_T *common;
+
+ common_type(type1->tt_member, type2->tt_member, &common, type_gap);
+ if (type1->tt_argcount == type2->tt_argcount
+ && type1->tt_argcount >= 0)
+ {
+ int argcount = type1->tt_argcount;
+ int i;
+
+ *dest = alloc_func_type(common, argcount, type_gap);
+ if (type1->tt_args != NULL && type2->tt_args != NULL)
+ {
+ (*dest)->tt_args = ALLOC_CLEAR_MULT(type_T *, argcount);
+ if ((*dest)->tt_args != NULL)
+ for (i = 0; i < argcount; ++i)
+ common_type(type1->tt_args[i], type2->tt_args[i],
+ &(*dest)->tt_args[i], type_gap);
+ }
+ }
+ else
+ *dest = alloc_func_type(common, -1, type_gap);
+ return;
+ }
}
*dest = &t_any;