]> granicus.if.org Git - vim/commitdiff
patch 8.2.0820: Vim9: function type isn't set until compiled v8.2.0820
authorBram Moolenaar <Bram@vim.org>
Sun, 24 May 2020 21:45:24 +0000 (23:45 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 24 May 2020 21:45:24 +0000 (23:45 +0200)
Problem:    Vim9: function type isn't set until compiled.
Solution:   Set function type early.

src/proto/vim9compile.pro
src/testdir/test_vim9_func.vim
src/userfunc.c
src/version.c
src/vim9compile.c

index 67c7224007d6af95c65bdfca4b94b5c162ad0b8b..0f3ebc394a60fcb367f9d02ed31ffba7ed760b26 100644 (file)
@@ -10,6 +10,7 @@ char_u *to_name_const_end(char_u *arg);
 int assignment_len(char_u *p, int *heredoc);
 int check_vim9_unlet(char_u *name);
 int compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx);
+void set_function_type(ufunc_T *ufunc);
 void delete_instr(isn_T *isn);
 void delete_def_function(ufunc_T *ufunc);
 void free_def_functions(void);
index d099bd2cb7789d52a73bf2ee7f6de4f0325d9fba..6c661111a0a175416a76b973adff00c8d2f210e5 100644 (file)
@@ -560,8 +560,7 @@ def Test_func_type_part()
   RefVoid = FuncNoArgNoRet
   RefVoid = FuncOneArgNoRet
   CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
-"  TODO: these should fail
-"  CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string')
+  CheckDefFailure(['let RefVoid: func: void', 'RefVoid = FuncNoArgRetString'], 'E1013: type mismatch, expected func() but got func(): string')
 
   let RefAny: func(): any
   RefAny = FuncNoArgRetNumber
@@ -573,8 +572,7 @@ def Test_func_type_part()
   RefNr = FuncNoArgRetNumber
   RefNr = FuncOneArgRetNumber
   CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgNoRet'], 'E1013: type mismatch, expected func(): number but got func()')
-"  TODO: should fail
-"  CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string')
+  CheckDefFailure(['let RefNr: func: number', 'RefNr = FuncNoArgRetString'], 'E1013: type mismatch, expected func(): number but got func(): string')
 
   let RefStr: func: string
   RefStr = FuncNoArgRetString
@@ -589,10 +587,9 @@ def Test_func_type_fails()
   CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncNoArgRetNumber'], 'E1013: type mismatch, expected func() but got func(): number')
   CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgNoRet'], 'E1013: type mismatch, expected func() but got func(number)')
   CheckDefFailure(['let Ref1: func()', 'Ref1 = FuncOneArgRetNumber'], 'E1013: type mismatch, expected func() but got func(number): number')
-"  TODO: these don't fail
-"  CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)')
-"  CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)')
-"  CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)')
+  CheckDefFailure(['let Ref1: func(bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(bool) but got func(bool, number)')
+  CheckDefFailure(['let Ref1: func(?bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(?bool) but got func(bool, number)')
+  CheckDefFailure(['let Ref1: func(...bool)', 'Ref1 = FuncTwoArgNoRet'], 'E1013: type mismatch, expected func(...bool) but got func(bool, number)')
 
   call CheckDefFailure(['let RefWrong: func(string ,number)'], 'E1068:')
   call CheckDefFailure(['let RefWrong: func(string,number)'], 'E1069:')
index f29a7b5c4ae5696620e3bcad39807ba59ac11430..bc92c2aaf3d95527cff94b3d008a9cf84680ad1d 100644 (file)
@@ -3284,6 +3284,9 @@ def_function(exarg_T *eap, char_u *name_arg)
        is_export = FALSE;
     }
 
+    if (eap->cmdidx == CMD_def)
+       set_function_type(fp);
+
     goto ret_free;
 
 erret:
index 63bf51d5c1e971f5539eb03365444f86ff1cf40c..a1e4a7f4876cb9673e5faf1c82fdd1018fe02e4f 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    820,
 /**/
     819,
 /**/
index d41dd53961bf4a8bf45532f0c9466dbc444a617d..7d302da83a17d19941390f305270a0c385e442ea 100644 (file)
@@ -6763,54 +6763,6 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
            ufunc->uf_flags |= FC_CLOSURE;
     }
 
-    {
-       int varargs = ufunc->uf_va_name != NULL;
-       int argcount = ufunc->uf_args.ga_len;
-
-       // Create a type for the function, with the return type and any
-       // argument types.
-       // A vararg is included in uf_args.ga_len but not in uf_arg_types.
-       // The type is included in "tt_args".
-       if (argcount > 0 || varargs)
-       {
-           ufunc->uf_func_type = alloc_func_type(ufunc->uf_ret_type,
-                                              argcount, &ufunc->uf_type_list);
-           // Add argument types to the function type.
-           if (func_type_add_arg_types(ufunc->uf_func_type,
-                                       argcount + varargs,
-                                       &ufunc->uf_type_list) == FAIL)
-           {
-               ret = FAIL;
-               goto erret;
-           }
-           ufunc->uf_func_type->tt_argcount = argcount + varargs;
-           ufunc->uf_func_type->tt_min_argcount =
-                                         argcount - ufunc->uf_def_args.ga_len;
-           if (ufunc->uf_arg_types == NULL)
-           {
-               int i;
-
-               // lambda does not have argument types.
-               for (i = 0; i < argcount; ++i)
-                   ufunc->uf_func_type->tt_args[i] = &t_any;
-           }
-           else
-               mch_memmove(ufunc->uf_func_type->tt_args,
-                            ufunc->uf_arg_types, sizeof(type_T *) * argcount);
-           if (varargs)
-           {
-               ufunc->uf_func_type->tt_args[argcount] =
-                       ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
-               ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS;
-           }
-       }
-       else
-           // No arguments, can use a predefined type.
-           ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type,
-                                              argcount, &ufunc->uf_type_list);
-
-    }
-
     ret = OK;
 
 erret:
@@ -6847,6 +6799,53 @@ erret:
     return ret;
 }
 
+    void
+set_function_type(ufunc_T *ufunc)
+{
+    int varargs = ufunc->uf_va_name != NULL;
+    int argcount = ufunc->uf_args.ga_len;
+
+    // Create a type for the function, with the return type and any
+    // argument types.
+    // A vararg is included in uf_args.ga_len but not in uf_arg_types.
+    // The type is included in "tt_args".
+    if (argcount > 0 || varargs)
+    {
+       ufunc->uf_func_type = alloc_func_type(ufunc->uf_ret_type,
+                                          argcount, &ufunc->uf_type_list);
+       // Add argument types to the function type.
+       if (func_type_add_arg_types(ufunc->uf_func_type,
+                                   argcount + varargs,
+                                   &ufunc->uf_type_list) == FAIL)
+           return;
+       ufunc->uf_func_type->tt_argcount = argcount + varargs;
+       ufunc->uf_func_type->tt_min_argcount =
+                                     argcount - ufunc->uf_def_args.ga_len;
+       if (ufunc->uf_arg_types == NULL)
+       {
+           int i;
+
+           // lambda does not have argument types.
+           for (i = 0; i < argcount; ++i)
+               ufunc->uf_func_type->tt_args[i] = &t_any;
+       }
+       else
+           mch_memmove(ufunc->uf_func_type->tt_args,
+                        ufunc->uf_arg_types, sizeof(type_T *) * argcount);
+       if (varargs)
+       {
+           ufunc->uf_func_type->tt_args[argcount] =
+                   ufunc->uf_va_type == NULL ? &t_any : ufunc->uf_va_type;
+           ufunc->uf_func_type->tt_flags = TTFLAG_VARARGS;
+       }
+    }
+    else
+       // No arguments, can use a predefined type.
+       ufunc->uf_func_type = get_func_type(ufunc->uf_ret_type,
+                                          argcount, &ufunc->uf_type_list);
+}
+
+
 /*
  * Delete an instruction, free what it contains.
  */