diff options
author | Bram Moolenaar <Bram@vim.org> | 2021-01-21 20:21:29 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2021-01-21 20:21:29 +0100 |
commit | e32e516dfa46e9c5965d278f96aaf57573de8ac4 (patch) | |
tree | e3603d67218152c9ad5fc8cffbd28b95d4ce1511 /src | |
parent | f904133e1a5ea84a124d3ece12b1f0a7392f1ca7 (diff) |
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)
Diffstat (limited to 'src')
-rw-r--r-- | src/testdir/test_vim9_builtin.vim | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_disassemble.vim | 2 | ||||
-rw-r--r-- | src/testdir/test_vim9_func.vim | 16 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9.h | 3 | ||||
-rw-r--r-- | src/vim9compile.c | 12 | ||||
-rw-r--r-- | src/vim9execute.c | 16 |
7 files changed, 41 insertions, 12 deletions
diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 50dc2a0735..06b5ecdba5 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 1aab9d5b38..f40bcf0ae0 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 da0a0e6432..fc1ed2120a 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 a73927045c..c911ed4608 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 b0c465deb2..c51be8ef62 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 e972033f0b..ead971feba 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 b533617fc7..7d1d079bb1 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; } |