summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-05-24 23:45:24 +0200
committerBram Moolenaar <Bram@vim.org>2020-05-24 23:45:24 +0200
commit6ff71d8b7fbdf667a2f119a2487302e240961816 (patch)
tree90e14c4469b447139f22501d5ff942441c90ece8
parentf40e51a880a95f94dbbbecc9476559506c2cc345 (diff)
patch 8.2.0820: Vim9: function type isn't set until compiledv8.2.0820
Problem: Vim9: function type isn't set until compiled. Solution: Set function type early.
-rw-r--r--src/proto/vim9compile.pro1
-rw-r--r--src/testdir/test_vim9_func.vim13
-rw-r--r--src/userfunc.c3
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c95
5 files changed, 58 insertions, 56 deletions
diff --git a/src/proto/vim9compile.pro b/src/proto/vim9compile.pro
index 67c7224007..0f3ebc394a 100644
--- a/src/proto/vim9compile.pro
+++ b/src/proto/vim9compile.pro
@@ -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);
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index d099bd2cb7..6c661111a0 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -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:')
diff --git a/src/userfunc.c b/src/userfunc.c
index f29a7b5c4a..bc92c2aaf3 100644
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -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:
diff --git a/src/version.c b/src/version.c
index 63bf51d5c1..a1e4a7f487 100644
--- 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 */
/**/
+ 820,
+/**/
819,
/**/
818,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index d41dd53961..7d302da83a 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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.
*/