]> granicus.if.org Git - vim/commitdiff
patch 8.2.2387: runtime type check does not mention argument index v8.2.2387
authorBram Moolenaar <Bram@vim.org>
Thu, 21 Jan 2021 19:21:29 +0000 (20:21 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 21 Jan 2021 19:21:29 +0000 (20:21 +0100)
Problem:    Runtime type check does not mention argument index.
Solution:   Add ct_arg_idx. (closes #7720)

src/testdir/test_vim9_builtin.vim
src/testdir/test_vim9_disassemble.vim
src/testdir/test_vim9_func.vim
src/version.c
src/vim9.h
src/vim9compile.c
src/vim9execute.c

index 50dc2a0735edf114773f1e88abe14177740337b5..06b5ecdba545ba5710d2bfc6cd516f5b1862f481 100644 (file)
@@ -263,7 +263,7 @@ def Test_extend_arg_types()
   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>')
+  CheckDefExecFailure(['extend([1], ["b", 1])'], 'E1013: Argument 2: type mismatch, expected list<number> but got list<any>')
 enddef
 
 def Test_extendnew()
index 1aab9d5b385c6480dccb8b49961dfa2a0f2a579d..f40bcf0ae025bbe0b6c6d685b9d83ee8cc8caed3 100644 (file)
@@ -934,7 +934,7 @@ def Test_disassemble_lambda_with_type()
         'return Ref(g:value)\_s*' ..
         '\d LOADG g:value\_s*' ..
         '\d LOAD $0\_s*' ..
-        '\d CHECKTYPE number stack\[-2\]\_s*' ..
+        '\d CHECKTYPE number stack\[-2\] arg 1\_s*' ..
         '\d PCALL (argc 1)\_s*' ..
         '\d RETURN',
         instr)
index da0a0e6432a88a7e52f2952eb7688abbf96f3878..fc1ed2120af19e0950aee9c7861fd9b1a26e37ff 100644 (file)
@@ -144,6 +144,22 @@ def Test_return_something()
   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',
index a73927045cf1277f7d211dba90f89b9cc2feb511..c911ed4608735da7e1e6b3529bf6d8bc56a9a367 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2387,
 /**/
     2386,
 /**/
index b0c465deb2a168178af9cde4ae4a6d86ac0de73b..c51be8ef626071393112f51e49dd422343c6de3a 100644 (file)
@@ -224,7 +224,8 @@ typedef struct {
 // arguments to ISN_CHECKTYPE
 typedef struct {
     type_T     *ct_type;
-    int                ct_off;     // offset in stack, -1 is bottom
+    char       ct_off;         // offset in stack, -1 is bottom
+    char       ct_arg_idx;     // argument index or zero
 } checktype_T;
 
 // arguments to ISN_STORENR
index e972033f0bad5bb379ceac8a06ac6710a539445f..ead971feba45f43381a36a61ee10b6e50be65c7f 100644 (file)
@@ -816,7 +816,8 @@ generate_COND2BOOL(cctx_T *cctx)
 generate_TYPECHECK(
        cctx_T      *cctx,
        type_T      *expected,
-       int         offset)
+       int         offset,
+       int         argidx)
 {
     isn_T      *isn;
     garray_T   *stack = &cctx->ctx_type_stack;
@@ -826,6 +827,7 @@ generate_TYPECHECK(
        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,7 +906,7 @@ need_type(
     // If it's a constant a runtime check makes no sense.
     if (!actual_is_const && use_typecheck(actual, expected))
     {
-       generate_TYPECHECK(cctx, expected, offset);
+       generate_TYPECHECK(cctx, expected, offset, arg_idx);
        return OK;
     }
 
@@ -1637,7 +1639,7 @@ generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call)
     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);
+       generate_TYPECHECK(cctx, maptype, -1, 1);
 
     return OK;
 }
@@ -1735,7 +1737,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
            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,
+           if (need_type(actual, expected, -argcount + i, i + 1, cctx,
                                                          TRUE, FALSE) == FAIL)
            {
                arg_type_mismatch(expected, actual, i + 1);
@@ -1852,7 +1854,7 @@ generate_PCALL(
                                             type->tt_argcount - 1]->tt_member;
                    else
                        expected = type->tt_args[i];
-                   if (need_type(actual, expected, offset, 0,
+                   if (need_type(actual, expected, offset, i + 1,
                                                    cctx, TRUE, FALSE) == FAIL)
                    {
                        arg_type_mismatch(expected, actual, i + 1);
index b533617fc732f80919059b287404e8b651af5bea..7d1d079bb19c93db677dffb69380298b58ab9cd6 100644 (file)
@@ -3242,7 +3242,8 @@ call_def_function(
 
                    tv = STACK_TV_BOT(ct->ct_off);
                    SOURCING_LNUM = iptr->isn_lnum;
-                   if (check_typval_type(ct->ct_type, tv, 0) == FAIL)
+                   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,11 +4236,18 @@ ex_disassemble(exarg_T *eap)
            case ISN_CHECKNR: smsg("%4d CHECKNR", current); break;
            case ISN_CHECKTYPE:
                  {
+                     checktype_T *ct = &iptr->isn_arg.type;
                      char *tofree;
 
-                     smsg("%4d CHECKTYPE %s stack[%d]", current,
-                             type_name(iptr->isn_arg.type.ct_type, &tofree),
-                             iptr->isn_arg.type.ct_off);
+                     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;
                  }