Patch 8.2.2387
Problem:    Runtime type check does not mention argument index.
Solution:   Add ct_arg_idx. (closes #7720)
Files:      src/vim9.h, src/vim9compile.c, src/vim9execute.c,
            src/testdir/test_vim9_builtin.vim,
            src/testdir/test_vim9_disassemble.vim,
            src/testdir/test_vim9_func.vim


*** ../vim-8.2.2386/src/vim9.h  2021-01-10 18:33:08.011683523 +0100
--- src/vim9.h  2021-01-21 20:03:18.551137054 +0100
***************
*** 224,230 ****
  // arguments to ISN_CHECKTYPE
  typedef struct {
      type_T    *ct_type;
!     int               ct_off;     // offset in stack, -1 is bottom
  } checktype_T;
  
  // arguments to ISN_STORENR
--- 224,231 ----
  // arguments to ISN_CHECKTYPE
  typedef struct {
      type_T    *ct_type;
!     char      ct_off;         // offset in stack, -1 is bottom
!     char      ct_arg_idx;     // argument index or zero
  } checktype_T;
  
  // arguments to ISN_STORENR
*** ../vim-8.2.2386/src/vim9compile.c   2021-01-21 12:34:11.441508288 +0100
--- src/vim9compile.c   2021-01-21 20:09:04.850377122 +0100
***************
*** 816,822 ****
  generate_TYPECHECK(
        cctx_T      *cctx,
        type_T      *expected,
!       int         offset)
  {
      isn_T     *isn;
      garray_T  *stack = &cctx->ctx_type_stack;
--- 816,823 ----
  generate_TYPECHECK(
        cctx_T      *cctx,
        type_T      *expected,
!       int         offset,
!       int         argidx)
  {
      isn_T     *isn;
      garray_T  *stack = &cctx->ctx_type_stack;
***************
*** 826,831 ****
--- 827,833 ----
        return FAIL;
      isn->isn_arg.type.ct_type = alloc_type(expected);
      isn->isn_arg.type.ct_off = offset;
+     isn->isn_arg.type.ct_arg_idx = argidx;
  
      // type becomes expected
      ((type_T **)stack->ga_data)[stack->ga_len + offset] = expected;
***************
*** 904,910 ****
      // If it's a constant a runtime check makes no sense.
      if (!actual_is_const && use_typecheck(actual, expected))
      {
!       generate_TYPECHECK(cctx, expected, offset);
        return OK;
      }
  
--- 906,912 ----
      // If it's a constant a runtime check makes no sense.
      if (!actual_is_const && use_typecheck(actual, expected))
      {
!       generate_TYPECHECK(cctx, expected, offset, arg_idx);
        return OK;
      }
  
***************
*** 1637,1643 ****
      if (maptype != NULL && maptype->tt_member != NULL
                                               && maptype->tt_member != &t_any)
        // Check that map() didn't change the item types.
!       generate_TYPECHECK(cctx, maptype, -1);
  
      return OK;
  }
--- 1639,1645 ----
      if (maptype != NULL && maptype->tt_member != NULL
                                               && maptype->tt_member != &t_any)
        // Check that map() didn't change the item types.
!       generate_TYPECHECK(cctx, maptype, -1, 1);
  
      return OK;
  }
***************
*** 1735,1741 ****
            else
                expected = ufunc->uf_va_type->tt_member;
            actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
!           if (need_type(actual, expected, -argcount + i, 0, cctx,
                                                          TRUE, FALSE) == FAIL)
            {
                arg_type_mismatch(expected, actual, i + 1);
--- 1737,1743 ----
            else
                expected = ufunc->uf_va_type->tt_member;
            actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
!           if (need_type(actual, expected, -argcount + i, i + 1, cctx,
                                                          TRUE, FALSE) == FAIL)
            {
                arg_type_mismatch(expected, actual, i + 1);
***************
*** 1852,1858 ****
                                             type->tt_argcount - 1]->tt_member;
                    else
                        expected = type->tt_args[i];
!                   if (need_type(actual, expected, offset, 0,
                                                    cctx, TRUE, FALSE) == FAIL)
                    {
                        arg_type_mismatch(expected, actual, i + 1);
--- 1854,1860 ----
                                             type->tt_argcount - 1]->tt_member;
                    else
                        expected = type->tt_args[i];
!                   if (need_type(actual, expected, offset, i + 1,
                                                    cctx, TRUE, FALSE) == FAIL)
                    {
                        arg_type_mismatch(expected, actual, i + 1);
*** ../vim-8.2.2386/src/vim9execute.c   2021-01-21 19:41:13.041961910 +0100
--- src/vim9execute.c   2021-01-21 20:17:13.337256669 +0100
***************
*** 3242,3248 ****
  
                    tv = STACK_TV_BOT(ct->ct_off);
                    SOURCING_LNUM = iptr->isn_lnum;
!                   if (check_typval_type(ct->ct_type, tv, 0) == FAIL)
                        goto on_error;
  
                    // number 0 is FALSE, number 1 is TRUE
--- 3242,3249 ----
  
                    tv = STACK_TV_BOT(ct->ct_off);
                    SOURCING_LNUM = iptr->isn_lnum;
!                   if (check_typval_type(ct->ct_type, tv, ct->ct_arg_idx)
!                                                                      == FAIL)
                        goto on_error;
  
                    // number 0 is FALSE, number 1 is TRUE
***************
*** 4235,4245 ****
            case ISN_CHECKNR: smsg("%4d CHECKNR", current); break;
            case ISN_CHECKTYPE:
                  {
                      char *tofree;
  
!                     smsg("%4d CHECKTYPE %s stack[%d]", current,
!                             type_name(iptr->isn_arg.type.ct_type, &tofree),
!                             iptr->isn_arg.type.ct_off);
                      vim_free(tofree);
                      break;
                  }
--- 4236,4253 ----
            case ISN_CHECKNR: smsg("%4d CHECKNR", current); break;
            case ISN_CHECKTYPE:
                  {
+                     checktype_T *ct = &iptr->isn_arg.type;
                      char *tofree;
  
!                     if (ct->ct_arg_idx == 0)
!                         smsg("%4d CHECKTYPE %s stack[%d]", current,
!                                         type_name(ct->ct_type, &tofree),
!                                         (int)ct->ct_off);
!                     else
!                         smsg("%4d CHECKTYPE %s stack[%d] arg %d", current,
!                                         type_name(ct->ct_type, &tofree),
!                                         (int)ct->ct_off,
!                                         (int)ct->ct_arg_idx);
                      vim_free(tofree);
                      break;
                  }
*** ../vim-8.2.2386/src/testdir/test_vim9_builtin.vim   2021-01-17 
16:16:19.997563189 +0100
--- src/testdir/test_vim9_builtin.vim   2021-01-21 20:15:05.993551944 +0100
***************
*** 263,269 ****
    CheckDefFailure(['extend({a: 1}, {b: 2}, 1)'], 'E1013: Argument 3: type 
mismatch, expected string but got number')
  
    CheckDefFailure(['extend([1], ["b"])'], 'E1013: Argument 2: type mismatch, 
expected list<number> but got list<string>')
!   CheckDefExecFailure(['extend([1], ["b", 1])'], 'E1012: Type mismatch; 
expected list<number> but got list<any>')
  enddef
  
  def Test_extendnew()
--- 263,269 ----
    CheckDefFailure(['extend({a: 1}, {b: 2}, 1)'], 'E1013: Argument 3: type 
mismatch, expected string but got number')
  
    CheckDefFailure(['extend([1], ["b"])'], 'E1013: Argument 2: type mismatch, 
expected list<number> but got list<string>')
!   CheckDefExecFailure(['extend([1], ["b", 1])'], 'E1013: Argument 2: type 
mismatch, expected list<number> but got list<any>')
  enddef
  
  def Test_extendnew()
*** ../vim-8.2.2386/src/testdir/test_vim9_disassemble.vim       2021-01-17 
16:16:19.997563189 +0100
--- src/testdir/test_vim9_disassemble.vim       2021-01-21 20:17:53.753162581 
+0100
***************
*** 934,940 ****
          'return Ref(g:value)\_s*' ..
          '\d LOADG g:value\_s*' ..
          '\d LOAD $0\_s*' ..
!         '\d CHECKTYPE number stack\[-2\]\_s*' ..
          '\d PCALL (argc 1)\_s*' ..
          '\d RETURN',
          instr)
--- 934,940 ----
          'return Ref(g:value)\_s*' ..
          '\d LOADG g:value\_s*' ..
          '\d LOAD $0\_s*' ..
!         '\d CHECKTYPE number stack\[-2\] arg 1\_s*' ..
          '\d PCALL (argc 1)\_s*' ..
          '\d RETURN',
          instr)
*** ../vim-8.2.2386/src/testdir/test_vim9_func.vim      2021-01-21 
19:41:13.041961910 +0100
--- src/testdir/test_vim9_func.vim      2021-01-21 20:12:40.573886859 +0100
***************
*** 144,149 ****
--- 144,165 ----
    assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but 
got string', '', 1, 'ReturnGlobal')
  enddef
  
+ def Test_check_argument_type()
+   var lines =<< trim END
+       vim9script
+       def Val(a: number, b: number): number
+         return 0
+       enddef
+       def Func()
+         var x: any = true
+         Val(0, x)
+       enddef
+       disass Func
+       Func()
+   END
+   CheckScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected 
number but got bool', 2)
+ enddef
+ 
  def Test_missing_return()
    CheckDefFailure(['def Missing(): number',
                     '  if g:cond',
*** ../vim-8.2.2386/src/version.c       2021-01-21 19:41:13.041961910 +0100
--- src/version.c       2021-01-21 20:04:10.207026612 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2387,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
202. You're amazed to find out Spam is a food.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            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/202101211922.10LJMAkx1979251%40masaka.moolenaar.net.

Raspunde prin e-mail lui