mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.2387: runtime type check does not mention argument index
Problem: Runtime type check does not mention argument index. Solution: Add ct_arg_idx. (closes #7720)
This commit is contained in:
@@ -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({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>')
|
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
|
enddef
|
||||||
|
|
||||||
def Test_extendnew()
|
def Test_extendnew()
|
||||||
|
@@ -934,7 +934,7 @@ def Test_disassemble_lambda_with_type()
|
|||||||
'return Ref(g:value)\_s*' ..
|
'return Ref(g:value)\_s*' ..
|
||||||
'\d LOADG g:value\_s*' ..
|
'\d LOADG g:value\_s*' ..
|
||||||
'\d LOAD $0\_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 PCALL (argc 1)\_s*' ..
|
||||||
'\d RETURN',
|
'\d RETURN',
|
||||||
instr)
|
instr)
|
||||||
|
@@ -144,6 +144,22 @@ def Test_return_something()
|
|||||||
assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
|
assert_fails('ReturnGlobal()', 'E1012: Type mismatch; expected number but got string', '', 1, 'ReturnGlobal')
|
||||||
enddef
|
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()
|
def Test_missing_return()
|
||||||
CheckDefFailure(['def Missing(): number',
|
CheckDefFailure(['def Missing(): number',
|
||||||
' if g:cond',
|
' if g:cond',
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2387,
|
||||||
/**/
|
/**/
|
||||||
2386,
|
2386,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -224,7 +224,8 @@ typedef struct {
|
|||||||
// arguments to ISN_CHECKTYPE
|
// arguments to ISN_CHECKTYPE
|
||||||
typedef struct {
|
typedef struct {
|
||||||
type_T *ct_type;
|
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;
|
} checktype_T;
|
||||||
|
|
||||||
// arguments to ISN_STORENR
|
// arguments to ISN_STORENR
|
||||||
|
@@ -816,7 +816,8 @@ generate_COND2BOOL(cctx_T *cctx)
|
|||||||
generate_TYPECHECK(
|
generate_TYPECHECK(
|
||||||
cctx_T *cctx,
|
cctx_T *cctx,
|
||||||
type_T *expected,
|
type_T *expected,
|
||||||
int offset)
|
int offset,
|
||||||
|
int argidx)
|
||||||
{
|
{
|
||||||
isn_T *isn;
|
isn_T *isn;
|
||||||
garray_T *stack = &cctx->ctx_type_stack;
|
garray_T *stack = &cctx->ctx_type_stack;
|
||||||
@@ -826,6 +827,7 @@ generate_TYPECHECK(
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
isn->isn_arg.type.ct_type = alloc_type(expected);
|
isn->isn_arg.type.ct_type = alloc_type(expected);
|
||||||
isn->isn_arg.type.ct_off = offset;
|
isn->isn_arg.type.ct_off = offset;
|
||||||
|
isn->isn_arg.type.ct_arg_idx = argidx;
|
||||||
|
|
||||||
// type becomes expected
|
// type becomes expected
|
||||||
((type_T **)stack->ga_data)[stack->ga_len + offset] = 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 it's a constant a runtime check makes no sense.
|
||||||
if (!actual_is_const && use_typecheck(actual, expected))
|
if (!actual_is_const && use_typecheck(actual, expected))
|
||||||
{
|
{
|
||||||
generate_TYPECHECK(cctx, expected, offset);
|
generate_TYPECHECK(cctx, expected, offset, arg_idx);
|
||||||
return OK;
|
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
|
if (maptype != NULL && maptype->tt_member != NULL
|
||||||
&& maptype->tt_member != &t_any)
|
&& maptype->tt_member != &t_any)
|
||||||
// Check that map() didn't change the item types.
|
// Check that map() didn't change the item types.
|
||||||
generate_TYPECHECK(cctx, maptype, -1);
|
generate_TYPECHECK(cctx, maptype, -1, 1);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -1735,7 +1737,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
|
|||||||
else
|
else
|
||||||
expected = ufunc->uf_va_type->tt_member;
|
expected = ufunc->uf_va_type->tt_member;
|
||||||
actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
|
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)
|
TRUE, FALSE) == FAIL)
|
||||||
{
|
{
|
||||||
arg_type_mismatch(expected, actual, i + 1);
|
arg_type_mismatch(expected, actual, i + 1);
|
||||||
@@ -1852,7 +1854,7 @@ generate_PCALL(
|
|||||||
type->tt_argcount - 1]->tt_member;
|
type->tt_argcount - 1]->tt_member;
|
||||||
else
|
else
|
||||||
expected = type->tt_args[i];
|
expected = type->tt_args[i];
|
||||||
if (need_type(actual, expected, offset, 0,
|
if (need_type(actual, expected, offset, i + 1,
|
||||||
cctx, TRUE, FALSE) == FAIL)
|
cctx, TRUE, FALSE) == FAIL)
|
||||||
{
|
{
|
||||||
arg_type_mismatch(expected, actual, i + 1);
|
arg_type_mismatch(expected, actual, i + 1);
|
||||||
|
@@ -3242,7 +3242,8 @@ call_def_function(
|
|||||||
|
|
||||||
tv = STACK_TV_BOT(ct->ct_off);
|
tv = STACK_TV_BOT(ct->ct_off);
|
||||||
SOURCING_LNUM = iptr->isn_lnum;
|
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;
|
goto on_error;
|
||||||
|
|
||||||
// number 0 is FALSE, number 1 is TRUE
|
// 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_CHECKNR: smsg("%4d CHECKNR", current); break;
|
||||||
case ISN_CHECKTYPE:
|
case ISN_CHECKTYPE:
|
||||||
{
|
{
|
||||||
|
checktype_T *ct = &iptr->isn_arg.type;
|
||||||
char *tofree;
|
char *tofree;
|
||||||
|
|
||||||
smsg("%4d CHECKTYPE %s stack[%d]", current,
|
if (ct->ct_arg_idx == 0)
|
||||||
type_name(iptr->isn_arg.type.ct_type, &tofree),
|
smsg("%4d CHECKTYPE %s stack[%d]", current,
|
||||||
iptr->isn_arg.type.ct_off);
|
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);
|
vim_free(tofree);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user