summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-01-21 20:21:29 +0100
committerBram Moolenaar <Bram@vim.org>2021-01-21 20:21:29 +0100
commite32e516dfa46e9c5965d278f96aaf57573de8ac4 (patch)
treee3603d67218152c9ad5fc8cffbd28b95d4ce1511
parentf904133e1a5ea84a124d3ece12b1f0a7392f1ca7 (diff)
downloadvim-git-e32e516dfa46e9c5965d278f96aaf57573de8ac4.tar.gz
patch 8.2.2387: runtime type check does not mention argument indexv8.2.2387
Problem: Runtime type check does not mention argument index. Solution: Add ct_arg_idx. (closes #7720)
-rw-r--r--src/testdir/test_vim9_builtin.vim2
-rw-r--r--src/testdir/test_vim9_disassemble.vim2
-rw-r--r--src/testdir/test_vim9_func.vim16
-rw-r--r--src/version.c2
-rw-r--r--src/vim9.h3
-rw-r--r--src/vim9compile.c12
-rw-r--r--src/vim9execute.c16
7 files changed, 41 insertions, 12 deletions
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim
index 50dc2a073..06b5ecdba 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -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()
diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim
index 1aab9d5b3..f40bcf0ae 100644
--- a/src/testdir/test_vim9_disassemble.vim
+++ b/src/testdir/test_vim9_disassemble.vim
@@ -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)
diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim
index da0a0e643..fc1ed2120 100644
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -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',
diff --git a/src/version.c b/src/version.c
index a73927045..c911ed460 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2387,
+/**/
2386,
/**/
2385,
diff --git a/src/vim9.h b/src/vim9.h
index b0c465deb..c51be8ef6 100644
--- a/src/vim9.h
+++ b/src/vim9.h
@@ -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
diff --git a/src/vim9compile.c b/src/vim9compile.c
index e972033f0..ead971feb 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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);
diff --git a/src/vim9execute.c b/src/vim9execute.c
index b533617fc..7d1d079bb 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -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;
}