diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-07-04 15:54:08 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-07-04 15:54:08 +0200 |
commit | 7a40ff00edd35cc4313d74a43e7a7b67cd24372d (patch) | |
tree | f635249daa4d7c43565d33eaf6015a2b624c24f6 /src | |
parent | 4197828dc666f2d258594f7f9461534d23cc50e4 (diff) |
patch 8.2.3100: Vim9: no error when using type with unknown number of argsv8.2.3100
Problem: Vim9: no error when using type with unknown number of arguments.
Solution: Do not ignore argument count of -1. (closes #8492)
Diffstat (limited to 'src')
-rw-r--r-- | src/evalfunc.c | 12 | ||||
-rw-r--r-- | src/proto/evalfunc.pro | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_assign.vim | 9 | ||||
-rw-r--r-- | src/testdir/test_vim9_expr.vim | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_func.vim | 2 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9type.c | 14 |
7 files changed, 35 insertions, 8 deletions
diff --git a/src/evalfunc.c b/src/evalfunc.c index e635116786..ec74fdeeae 100644 --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -2055,6 +2055,18 @@ internal_func_check_arg_types( } /* + * Get the argument count for function "idx". + * "argcount" is the total argument count, "min_argcount" the non-optional + * argument count. + */ + void +internal_func_get_argcount(int idx, int *argcount, int *min_argcount) +{ + *argcount = global_functions[idx].f_max_argc; + *min_argcount = global_functions[idx].f_min_argc; +} + +/* * Call the "f_retfunc" function to obtain the return type of function "idx". * "argtypes" is the list of argument types or NULL when there are no * arguments. diff --git a/src/proto/evalfunc.pro b/src/proto/evalfunc.pro index c1ac55f5b9..3faff292a7 100644 --- a/src/proto/evalfunc.pro +++ b/src/proto/evalfunc.pro @@ -6,6 +6,7 @@ int find_internal_func(char_u *name); int has_internal_func(char_u *name); char *internal_func_name(int idx); int internal_func_check_arg_types(type_T **types, int idx, int argcount, cctx_T *cctx); +void internal_func_get_argcount(int idx, int *argcount, int *min_argcount); type_T *internal_func_ret_type(int idx, int argcount, type_T **argtypes); int internal_func_is_map(int idx); int check_internal_func(int idx, int argcount); @@ -21,7 +22,6 @@ void f_has(typval_T *argvars, typval_T *rettv); int dynamic_feature(char_u *feature); void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv); void range_list_materialize(list_T *list); -float_T vim_round(float_T f); long do_searchpair(char_u *spat, char_u *mpat, char_u *epat, int dir, typval_T *skip, int flags, pos_T *match_pos, linenr_T lnum_stop, long time_limit); void f_string(typval_T *argvars, typval_T *rettv); /* vim: set ft=c : */ diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 86f890ea09..92ffa0055c 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -650,6 +650,15 @@ def Test_assignment_list() d.dd[0] = 0 END CheckDefExecFailure(lines, 'E1147:', 2) + + lines =<< trim END + def OneArg(x: bool) + enddef + def TwoArgs(x: bool, y: bool) + enddef + var fl: list<func(bool, bool, bool)> = [OneArg, TwoArgs] + END + CheckDefExecAndScriptFailure(lines, 'E1012:', 5) enddef def Test_assignment_list_any_index() diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index 22c68f4ae4..1e99e9568d 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -57,7 +57,7 @@ def Test_expr1_trinary() assert_equal(function('len'), Res) var RetOne: func(string): number = function('len') - var RetTwo: func(string): number = function('winnr') + var RetTwo: func(string): number = function('charcol') var RetThat: func = g:atrue ? RetOne : RetTwo assert_equal(function('len'), RetThat) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index f4142ee851..89cdee7437 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1030,7 +1030,7 @@ def Test_pass_legacy_lambda_to_def_func() lines =<< trim END vim9script - def g:TestFunc(f: func()) + def g:TestFunc(f: func) enddef legacy call g:TestFunc({-> 0}) delfunc g:TestFunc diff --git a/src/version.c b/src/version.c index 062e856e04..298fd87996 100644 --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3100, +/**/ 3099, /**/ 3098, diff --git a/src/vim9type.c b/src/vim9type.c index 91dc3fe607..c92e063bb1 100644 --- a/src/vim9type.c +++ b/src/vim9type.c @@ -260,6 +260,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member) type_T *type; type_T *member_type = &t_any; int argcount = 0; + int min_argcount = 0; if (tv->v_type == VAR_NUMBER) return &t_number; @@ -337,8 +338,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member) if (idx >= 0) { - // TODO: get actual arg count and types - argcount = -1; + internal_func_get_argcount(idx, &argcount, &min_argcount); member_type = internal_func_ret_type(idx, 0, NULL); } else @@ -364,6 +364,7 @@ typval2type_int(typval_T *tv, int copyID, garray_T *type_gap, int do_member) return NULL; type->tt_type = tv->v_type; type->tt_argcount = argcount; + type->tt_min_argcount = min_argcount; type->tt_member = member_type; return type; @@ -525,9 +526,9 @@ check_type(type_T *expected, type_T *actual, int give_msg, where_T where) ret = check_type(expected->tt_member, actual->tt_member, FALSE, where); if (ret == OK && expected->tt_argcount != -1 - && actual->tt_argcount != -1 - && (actual->tt_argcount < expected->tt_min_argcount - || actual->tt_argcount > expected->tt_argcount)) + && (actual->tt_argcount == -1 + || (actual->tt_argcount < expected->tt_min_argcount + || actual->tt_argcount > expected->tt_argcount))) ret = FAIL; if (ret == OK && expected->tt_args != NULL && actual->tt_args != NULL) @@ -1032,7 +1033,10 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap) } } else + // Use -1 for "tt_argcount" to indicate an unknown number of + // arguments. *dest = alloc_func_type(common, -1, type_gap); + // Use the minimum of min_argcount. (*dest)->tt_min_argcount = type1->tt_min_argcount < type2->tt_min_argcount |