Mirror of the Vim source from https://github.com/vim/vim
Révision | 374c7d5a096aefa941ac5ff0d16df365868be44d (tree) |
---|---|
l'heure | 2022-01-17 03:15:03 |
Auteur | Bram Moolenaar <Bram@vim....> |
Commiter | Bram Moolenaar |
patch 8.2.4114: Vim9: type checking for a funcref does not work for method
Commit: https://github.com/vim/vim/commit/c84287d6d8dd055bb6e30605465a23a8addb6fde
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 16 18:06:21 2022 +0000
@@ -12,12 +12,11 @@ | ||
12 | 12 | type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap); |
13 | 13 | int check_typval_arg_type(type_T *expected, typval_T *actual_tv, char *func_name, int arg_idx); |
14 | 14 | int check_typval_type(type_T *expected, typval_T *actual_tv, where_T where); |
15 | -void type_mismatch(type_T *expected, type_T *actual); | |
16 | 15 | void arg_type_mismatch(type_T *expected, type_T *actual, int arg_idx); |
17 | 16 | void type_mismatch_where(type_T *expected, type_T *actual, where_T where); |
18 | 17 | int check_type(type_T *expected, type_T *actual, int give_msg, where_T where); |
19 | 18 | int check_type_maybe(type_T *expected, type_T *actual, int give_msg, where_T where); |
20 | -int check_argument_types(type_T *type, typval_T *argvars, int argcount, char_u *name); | |
19 | +int check_argument_types(type_T *type, typval_T *argvars, int argcount, typval_T *base_tv, char_u *name); | |
21 | 20 | char_u *skip_type(char_u *start, int optional); |
22 | 21 | type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error); |
23 | 22 | int equal_type(type_T *type1, type_T *type2, int flags); |
@@ -3136,6 +3136,14 @@ | ||
3136 | 3136 | var sorted = [3, 1, 2] |
3137 | 3137 | -> sort() |
3138 | 3138 | assert_equal([1, 2, 3], sorted) |
3139 | + | |
3140 | + def SetNumber(n: number) | |
3141 | + g:number = n | |
3142 | + enddef | |
3143 | + const Setit = SetNumber | |
3144 | + len('text')->Setit() | |
3145 | + assert_equal(4, g:number) | |
3146 | + unlet g:number | |
3139 | 3147 | END |
3140 | 3148 | CheckDefAndScriptSuccess(lines) |
3141 | 3149 |
@@ -3386,7 +3386,8 @@ | ||
3386 | 3386 | && funcexe->fe_evaluate) |
3387 | 3387 | { |
3388 | 3388 | // Check that the argument types are OK for the types of the funcref. |
3389 | - if (check_argument_types(funcexe->fe_check_type, argvars, argcount, | |
3389 | + if (check_argument_types(funcexe->fe_check_type, | |
3390 | + argvars, argcount, funcexe->fe_basetv, | |
3390 | 3391 | (name != NULL) ? name : funcname) == FAIL) |
3391 | 3392 | error = FCERR_OTHER; |
3392 | 3393 | } |
@@ -751,6 +751,8 @@ | ||
751 | 751 | static int included_patches[] = |
752 | 752 | { /* Add new patch number below this line */ |
753 | 753 | /**/ |
754 | + 4114, | |
755 | +/**/ | |
754 | 756 | 4113, |
755 | 757 | /**/ |
756 | 758 | 4112, |
@@ -687,6 +687,7 @@ | ||
687 | 687 | |
688 | 688 | /* |
689 | 689 | * Check that the arguments of "type" match "argvars[argcount]". |
690 | + * "base_tv" is from "expr->Func()". | |
690 | 691 | * Return OK/FAIL. |
691 | 692 | */ |
692 | 693 | int |
@@ -694,19 +695,21 @@ | ||
694 | 695 | type_T *type, |
695 | 696 | typval_T *argvars, |
696 | 697 | int argcount, |
698 | + typval_T *base_tv, | |
697 | 699 | char_u *name) |
698 | 700 | { |
699 | 701 | int varargs = (type->tt_flags & TTFLAG_VARARGS) ? 1 : 0; |
700 | 702 | int i; |
703 | + int totcount = argcount + (base_tv == NULL ? 0 : 1); | |
701 | 704 | |
702 | 705 | if (type->tt_type != VAR_FUNC && type->tt_type != VAR_PARTIAL) |
703 | 706 | return OK; // just in case |
704 | - if (argcount < type->tt_min_argcount - varargs) | |
707 | + if (totcount < type->tt_min_argcount - varargs) | |
705 | 708 | { |
706 | 709 | semsg(_(e_not_enough_arguments_for_function_str), name); |
707 | 710 | return FAIL; |
708 | 711 | } |
709 | - if (!varargs && type->tt_argcount >= 0 && argcount > type->tt_argcount) | |
712 | + if (!varargs && type->tt_argcount >= 0 && totcount > type->tt_argcount) | |
710 | 713 | { |
711 | 714 | semsg(_(e_too_many_arguments_for_function_str), name); |
712 | 715 | return FAIL; |
@@ -715,15 +718,25 @@ | ||
715 | 718 | return OK; // cannot check |
716 | 719 | |
717 | 720 | |
718 | - for (i = 0; i < argcount; ++i) | |
721 | + for (i = 0; i < totcount; ++i) | |
719 | 722 | { |
720 | - type_T *expected; | |
723 | + type_T *expected; | |
724 | + typval_T *tv; | |
721 | 725 | |
726 | + if (base_tv != NULL) | |
727 | + { | |
728 | + if (i == 0) | |
729 | + tv = base_tv; | |
730 | + else | |
731 | + tv = &argvars[i - 1]; | |
732 | + } | |
733 | + else | |
734 | + tv = &argvars[i]; | |
722 | 735 | if (varargs && i >= type->tt_argcount - 1) |
723 | 736 | expected = type->tt_args[type->tt_argcount - 1]->tt_member; |
724 | 737 | else |
725 | 738 | expected = type->tt_args[i]; |
726 | - if (check_typval_arg_type(expected, &argvars[i], NULL, i + 1) == FAIL) | |
739 | + if (check_typval_arg_type(expected, tv, NULL, i + 1) == FAIL) | |
727 | 740 | return FAIL; |
728 | 741 | } |
729 | 742 | return OK; |