mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.2.3310: Vim9: unpack assignment does not mention source of type error
Problem: Vim9: unpack assignment does not mention source of type error. Solution: Mention the argument number. (closes #8719)
This commit is contained in:
@@ -414,6 +414,22 @@ def Test_assign_unpack()
|
|||||||
[x, y] = g:values
|
[x, y] = g:values
|
||||||
END
|
END
|
||||||
CheckDefExecAndScriptFailure(lines, 'E1163: Variable 2: type mismatch, expected string but got number')
|
CheckDefExecAndScriptFailure(lines, 'E1163: Variable 2: type mismatch, expected string but got number')
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
var x: number
|
||||||
|
var y: number
|
||||||
|
var z: string
|
||||||
|
[x, y, z] = [1, 2, 3]
|
||||||
|
END
|
||||||
|
CheckDefAndScriptFailure(lines, 'E1163: Variable 3: type mismatch, expected string but got number')
|
||||||
|
|
||||||
|
lines =<< trim END
|
||||||
|
var x: number
|
||||||
|
var y: string
|
||||||
|
var z: string
|
||||||
|
[x, y, z] = [1, '2', 3]
|
||||||
|
END
|
||||||
|
CheckDefExecAndScriptFailure(lines, 'E1163: Variable 3: type mismatch, expected string but got number')
|
||||||
enddef
|
enddef
|
||||||
|
|
||||||
def Test_assign_linebreak()
|
def Test_assign_linebreak()
|
||||||
|
@@ -441,10 +441,10 @@ def Test_disassemble_list_assign()
|
|||||||
'\d CHECKTYPE list<any> stack\[-1\]\_s*' ..
|
'\d CHECKTYPE list<any> stack\[-1\]\_s*' ..
|
||||||
'\d CHECKLEN >= 2\_s*' ..
|
'\d CHECKLEN >= 2\_s*' ..
|
||||||
'\d\+ ITEM 0\_s*' ..
|
'\d\+ ITEM 0\_s*' ..
|
||||||
'\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
|
'\d\+ CHECKTYPE string stack\[-1\] arg 1\_s*' ..
|
||||||
'\d\+ STORE $0\_s*' ..
|
'\d\+ STORE $0\_s*' ..
|
||||||
'\d\+ ITEM 1\_s*' ..
|
'\d\+ ITEM 1\_s*' ..
|
||||||
'\d\+ CHECKTYPE string stack\[-1\]\_s*' ..
|
'\d\+ CHECKTYPE string stack\[-1\] arg 2\_s*' ..
|
||||||
'\d\+ STORE $1\_s*' ..
|
'\d\+ STORE $1\_s*' ..
|
||||||
'\d\+ SLICE 2\_s*' ..
|
'\d\+ SLICE 2\_s*' ..
|
||||||
'\d\+ STORE $2\_s*' ..
|
'\d\+ STORE $2\_s*' ..
|
||||||
|
@@ -755,6 +755,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 */
|
||||||
|
/**/
|
||||||
|
3310,
|
||||||
/**/
|
/**/
|
||||||
3309,
|
3309,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -1039,6 +1039,42 @@ use_typecheck(type_T *actual, type_T *expected)
|
|||||||
* If "actual_is_const" is TRUE then the type won't change at runtime, do not
|
* If "actual_is_const" is TRUE then the type won't change at runtime, do not
|
||||||
* generate a TYPECHECK.
|
* generate a TYPECHECK.
|
||||||
*/
|
*/
|
||||||
|
static int
|
||||||
|
need_type_where(
|
||||||
|
type_T *actual,
|
||||||
|
type_T *expected,
|
||||||
|
int offset,
|
||||||
|
where_T where,
|
||||||
|
cctx_T *cctx,
|
||||||
|
int silent,
|
||||||
|
int actual_is_const)
|
||||||
|
{
|
||||||
|
if (expected == &t_bool && actual != &t_bool
|
||||||
|
&& (actual->tt_flags & TTFLAG_BOOL_OK))
|
||||||
|
{
|
||||||
|
// Using "0", "1" or the result of an expression with "&&" or "||" as a
|
||||||
|
// boolean is OK but requires a conversion.
|
||||||
|
generate_2BOOL(cctx, FALSE, offset);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_type(expected, actual, FALSE, where) == OK)
|
||||||
|
return OK;
|
||||||
|
|
||||||
|
// If the actual type can be the expected type add a runtime check.
|
||||||
|
// If it's a constant a runtime check makes no sense.
|
||||||
|
if ((!actual_is_const || actual == &t_any)
|
||||||
|
&& use_typecheck(actual, expected))
|
||||||
|
{
|
||||||
|
generate_TYPECHECK(cctx, expected, offset, where.wt_index);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!silent)
|
||||||
|
type_mismatch_where(expected, actual, where);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
need_type(
|
need_type(
|
||||||
type_T *actual,
|
type_T *actual,
|
||||||
@@ -1051,31 +1087,9 @@ need_type(
|
|||||||
{
|
{
|
||||||
where_T where = WHERE_INIT;
|
where_T where = WHERE_INIT;
|
||||||
|
|
||||||
if (expected == &t_bool && actual != &t_bool
|
|
||||||
&& (actual->tt_flags & TTFLAG_BOOL_OK))
|
|
||||||
{
|
|
||||||
// Using "0", "1" or the result of an expression with "&&" or "||" as a
|
|
||||||
// boolean is OK but requires a conversion.
|
|
||||||
generate_2BOOL(cctx, FALSE, offset);
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
where.wt_index = arg_idx;
|
where.wt_index = arg_idx;
|
||||||
if (check_type(expected, actual, FALSE, where) == OK)
|
return need_type_where(actual, expected, offset, where,
|
||||||
return OK;
|
cctx, silent, actual_is_const);
|
||||||
|
|
||||||
// If the actual type can be the expected type add a runtime check.
|
|
||||||
// If it's a constant a runtime check makes no sense.
|
|
||||||
if ((!actual_is_const || actual == &t_any)
|
|
||||||
&& use_typecheck(actual, expected))
|
|
||||||
{
|
|
||||||
generate_TYPECHECK(cctx, expected, offset, arg_idx);
|
|
||||||
return OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!silent)
|
|
||||||
arg_type_mismatch(expected, actual, arg_idx);
|
|
||||||
return FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -7004,14 +7018,17 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
|||||||
else if (*op == '=')
|
else if (*op == '=')
|
||||||
{
|
{
|
||||||
type_T *use_type = lhs.lhs_lvar->lv_type;
|
type_T *use_type = lhs.lhs_lvar->lv_type;
|
||||||
|
where_T where = WHERE_INIT;
|
||||||
|
|
||||||
// Without operator check type here, otherwise below.
|
// Without operator check type here, otherwise below.
|
||||||
// Use the line number of the assignment.
|
// Use the line number of the assignment.
|
||||||
SOURCING_LNUM = start_lnum;
|
SOURCING_LNUM = start_lnum;
|
||||||
|
where.wt_index = var_count > 0 ? var_idx + 1 : 0;
|
||||||
|
where.wt_variable = var_count > 0;
|
||||||
if (lhs.lhs_has_index)
|
if (lhs.lhs_has_index)
|
||||||
use_type = lhs.lhs_member_type;
|
use_type = lhs.lhs_member_type;
|
||||||
if (need_type(rhs_type, use_type, -1, 0, cctx,
|
if (need_type_where(rhs_type, use_type, -1, where,
|
||||||
FALSE, is_const) == FAIL)
|
cctx, FALSE, is_const) == FAIL)
|
||||||
goto theend;
|
goto theend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user