]> granicus.if.org Git - vim/commitdiff
patch 8.2.0552: Vim9: some errors not covered by tests v8.2.0552
authorBram Moolenaar <Bram@vim.org>
Sun, 12 Apr 2020 12:39:53 +0000 (14:39 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 12 Apr 2020 12:39:53 +0000 (14:39 +0200)
Problem:    Vim9: some errors not covered by tests.
Solution:   Add more tests.  Check Funcref argument types.

src/testdir/test_vim9_func.vim
src/version.c
src/vim9compile.c

index 57ecf51ff40efc2764cb52bbc213859a4fb6625a..a40ac3e99f4ed81e0b22d09e0ce0bcbbbd152e58 100644 (file)
@@ -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
index 4959ab712282fc89ea0a9d7a2bc519b8c75ffff4..2985dd0b05ecd919997e5442aebef87e51808fb0 100644 (file)
@@ -738,6 +738,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    552,
 /**/
     551,
 /**/
index 33c4a6cdf5bfc579edac3a7a9957d5d817dd36ee..772e29f353d1fb8c64f2cfa068358c7e4a6be788 100644 (file)
@@ -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;