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 -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220116180648.35B511C0519%40moolenaar.net.

Raspunde prin e-mail lui