Patch 8.2.4114

7 views
Skip to first unread message

Bram Moolenaar

unread,
Jan 16, 2022, 1:06:54 PM1/16/22
to vim...@googlegroups.com

Patch 8.2.4114
Problem: Vim9: type checking for a funcref does not work for when it is
used in a method.
Solution: Pass the base to where the type is checked.
Files: src/vim9type.c, src/proto/vim9type.pro, src/userfunc.c,
src/testdir/test_vim9_expr.vim


*** ../vim-8.2.4113/src/vim9type.c 2022-01-13 21:15:17.241958539 +0000
--- src/vim9type.c 2022-01-16 18:05:04.815888199 +0000
***************
*** 687,692 ****
--- 687,693 ----

/*
* Check that the arguments of "type" match "argvars[argcount]".
+ * "base_tv" is from "expr->Func()".
* Return OK/FAIL.
*/
int
***************
*** 694,712 ****
type_T *type,
typval_T *argvars,
int argcount,
char_u *name)
{
int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
int i;

if (type->tt_type != VAR_FUNC && type->tt_type != VAR_PARTIAL)
return OK; // just in case
! if (argcount < type->tt_min_argcount - varargs)
{
semsg(_(e_not_enough_arguments_for_function_str), name);
return FAIL;
}
! if (!varargs && type->tt_argcount >= 0 && argcount > type->tt_argcount)
{
semsg(_(e_too_many_arguments_for_function_str), name);
return FAIL;
--- 695,715 ----
type_T *type,
typval_T *argvars,
int argcount,
+ typval_T *base_tv,
char_u *name)
{
int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0;
int i;
+ int totcount = argcount + (base_tv == NULL ? 0 : 1);

if (type->tt_type != VAR_FUNC && type->tt_type != VAR_PARTIAL)
return OK; // just in case
! if (totcount < type->tt_min_argcount - varargs)
{
semsg(_(e_not_enough_arguments_for_function_str), name);
return FAIL;
}
! if (!varargs && type->tt_argcount >= 0 && totcount > type->tt_argcount)
{
semsg(_(e_too_many_arguments_for_function_str), name);
return FAIL;
***************
*** 715,729 ****
return OK; // cannot check


! for (i = 0; i < argcount; ++i)
{
! type_T *expected;

if (varargs && i >= type->tt_argcount - 1)
expected = type->tt_args[type->tt_argcount - 1]->tt_member;
else
expected = type->tt_args[i];
! if (check_typval_arg_type(expected, &argvars[i], NULL, i + 1) == FAIL)
return FAIL;
}
return OK;
--- 718,742 ----
return OK; // cannot check


! for (i = 0; i < totcount; ++i)
{
! type_T *expected;
! typval_T *tv;

+ if (base_tv != NULL)
+ {
+ if (i == 0)
+ tv = base_tv;
+ else
+ tv = &argvars[i - 1];
+ }
+ else
+ tv = &argvars[i];
if (varargs && i >= type->tt_argcount - 1)
expected = type->tt_args[type->tt_argcount - 1]->tt_member;
else
expected = type->tt_args[i];
! if (check_typval_arg_type(expected, tv, NULL, i + 1) == FAIL)
return FAIL;
}
return OK;
*** ../vim-8.2.4113/src/proto/vim9type.pro 2022-01-04 15:16:57.879864882 +0000
--- src/proto/vim9type.pro 2022-01-16 18:00:09.352062881 +0000
***************
*** 12,23 ****
type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap);
int check_typval_arg_type(type_T *expected, typval_T *actual_tv, char *func_name, int arg_idx);
int check_typval_type(type_T *expected, typval_T *actual_tv, where_T where);
- void type_mismatch(type_T *expected, type_T *actual);
void arg_type_mismatch(type_T *expected, type_T *actual, int arg_idx);
void type_mismatch_where(type_T *expected, type_T *actual, where_T where);
int check_type(type_T *expected, type_T *actual, int give_msg, where_T where);
int check_type_maybe(type_T *expected, type_T *actual, int give_msg, where_T where);
! int check_argument_types(type_T *type, typval_T *argvars, int argcount, char_u *name);
char_u *skip_type(char_u *start, int optional);
type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error);
int equal_type(type_T *type1, type_T *type2, int flags);
--- 12,22 ----
type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap);
int check_typval_arg_type(type_T *expected, typval_T *actual_tv, char *func_name, int arg_idx);
int check_typval_type(type_T *expected, typval_T *actual_tv, where_T where);
void arg_type_mismatch(type_T *expected, type_T *actual, int arg_idx);
void type_mismatch_where(type_T *expected, type_T *actual, where_T where);
int check_type(type_T *expected, type_T *actual, int give_msg, where_T where);
int check_type_maybe(type_T *expected, type_T *actual, int give_msg, where_T where);
! int check_argument_types(type_T *type, typval_T *argvars, int argcount, typval_T *base_tv, char_u *name);
char_u *skip_type(char_u *start, int optional);
type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error);
int equal_type(type_T *type1, type_T *type2, int flags);
*** ../vim-8.2.4113/src/userfunc.c 2022-01-13 21:15:17.233958564 +0000
--- src/userfunc.c 2022-01-16 17:53:30.704180828 +0000
***************
*** 3386,3392 ****
&& funcexe->fe_evaluate)
{
// Check that the argument types are OK for the types of the funcref.
! if (check_argument_types(funcexe->fe_check_type, argvars, argcount,
(name != NULL) ? name : funcname) == FAIL)
error = FCERR_OTHER;
}
--- 3386,3393 ----
&& funcexe->fe_evaluate)
{
// Check that the argument types are OK for the types of the funcref.
! if (check_argument_types(funcexe->fe_check_type,
! argvars, argcount, funcexe->fe_basetv,
(name != NULL) ? name : funcname) == FAIL)
error = FCERR_OTHER;
}
*** ../vim-8.2.4113/src/testdir/test_vim9_expr.vim 2022-01-10 18:50:48.419345326 +0000
--- src/testdir/test_vim9_expr.vim 2022-01-16 18:03:24.591952890 +0000
***************
*** 3136,3141 ****
--- 3136,3149 ----
var sorted = [3, 1, 2]
-> sort()
assert_equal([1, 2, 3], sorted)
+
+ def SetNumber(n: number)
+ g:number = n
+ enddef
+ const Setit = SetNumber
+ len('text')->Setit()
+ assert_equal(4, g:number)
+ unlet g:number
END
CheckDefAndScriptSuccess(lines)

*** ../vim-8.2.4113/src/version.c 2022-01-16 15:52:32.020847559 +0000
--- src/version.c 2022-01-16 18:00:38.600048025 +0000
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 4114,
/**/

--
CUSTOMER: Well, can you hang around a couple of minutes? He won't be
long.
MORTICIAN: Naaah, I got to go on to Robinson's -- they've lost nine today.
CUSTOMER: Well, when is your next round?
MORTICIAN: Thursday.
DEAD PERSON: I think I'll go for a walk.
The Quest for the Holy Grail (Monty Python)

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
Reply all
Reply to author
Forward
0 new messages