Patch 8.2.2501
Problem: Not always clear where an error is reported.
Solution: Add the where_T structure and pass it around. (closes #7796)
Files: src/structs.h, src/vim9type.c, src/proto/vim9type.pro,
src/errors.h, src/evalvars.c, src/proto/evalvars.pro, src/eval.c,
src/proto/eval.pro, src/vim9execute.c, src/vim9script.c,
src/proto/vim9script.pro, src/dict.c, src/list.c,
src/vim9compile.c, src/testdir/test_vim9_assign.vim
*** ../vim-8.2.2500/src/structs.h 2021-02-07 12:12:39.377215418 +0100
--- src/structs.h 2021-02-11 20:45:26.822390345 +0100
***************
*** 4387,4389 ****
--- 4387,4396 ----
MAGIC_ON = 3, // "\m" or 'magic'
MAGIC_ALL = 4 // "\v" very magic
} magic_T;
+
+ // Struct used to pass to error messages about where the error happened.
+ typedef struct {
+ char wt_index; // argument or variable index, 0 means unknown
+ char wt_variable; // "variable" when TRUE, "argument" otherwise
+ } where_T;
+
*** ../vim-8.2.2500/src/vim9type.c 2021-02-07 18:06:25.266692335 +0100
--- src/vim9type.c 2021-02-11 21:05:07.873763997 +0100
***************
*** 399,411 ****
return typval2type(tv, type_gap);
}
/*
* Return FAIL if "expected" and "actual" don't match.
* When "argidx" > 0 it is included in the error message.
*/
int
! check_typval_type(type_T *expected, typval_T *actual_tv, int argidx)
{
garray_T type_list;
type_T *actual_type;
--- 399,420 ----
return typval2type(tv, type_gap);
}
+ int
+ check_typval_arg_type(type_T *expected, typval_T *actual_tv, int arg_idx)
+ {
+ where_T where;
+
+ where.wt_index = arg_idx;
+ where.wt_variable = FALSE;
+ return check_typval_type(expected, actual_tv, where);
+ }
/*
* Return FAIL if "expected" and "actual" don't match.
* When "argidx" > 0 it is included in the error message.
*/
int
! check_typval_type(type_T *expected, typval_T *actual_tv, where_T where)
{
garray_T type_list;
type_T *actual_type;
***************
*** 414,420 ****
ga_init2(&type_list, sizeof(type_T *), 10);
actual_type = typval2type(actual_tv, &type_list);
if (actual_type != NULL)
! res = check_type(expected, actual_type, TRUE, argidx);
clear_type_list(&type_list);
return res;
}
--- 423,429 ----
ga_init2(&type_list, sizeof(type_T *), 10);
actual_type = typval2type(actual_tv, &type_list);
if (actual_type != NULL)
! res = check_type(expected, actual_type, TRUE, where);
clear_type_list(&type_list);
return res;
}
***************
*** 426,440 ****
}
void
! arg_type_mismatch(type_T *expected, type_T *actual, int argidx)
{
char *tofree1, *tofree2;
char *typename1 = type_name(expected, &tofree1);
char *typename2 = type_name(actual, &tofree2);
! if (argidx > 0)
! semsg(_(e_argument_nr_type_mismatch_expected_str_but_got_str),
! argidx, typename1, typename2);
else
semsg(_(e_type_mismatch_expected_str_but_got_str),
typename1, typename2);
--- 435,463 ----
}
void
! arg_type_mismatch(type_T *expected, type_T *actual, int arg_idx)
! {
! where_T where;
!
! where.wt_index = arg_idx;
! where.wt_variable = FALSE;
! type_mismatch_where(expected, actual, where);
! }
!
! void
! type_mismatch_where(type_T *expected, type_T *actual, where_T where)
{
char *tofree1, *tofree2;
char *typename1 = type_name(expected, &tofree1);
char *typename2 = type_name(actual, &tofree2);
! if (where.wt_index > 0)
! {
! semsg(_(where.wt_variable
! ? e_variable_nr_type_mismatch_expected_str_but_got_str
! : e_argument_nr_type_mismatch_expected_str_but_got_str),
! where.wt_index, typename1, typename2);
! }
else
semsg(_(e_type_mismatch_expected_str_but_got_str),
typename1, typename2);
***************
*** 448,454 ****
* When "argidx" > 0 it is included in the error message.
*/
int
! check_type(type_T *expected, type_T *actual, int give_msg, int argidx)
{
int ret = OK;
--- 471,477 ----
* When "argidx" > 0 it is included in the error message.
*/
int
! check_type(type_T *expected, type_T *actual, int give_msg, where_T where)
{
int ret = OK;
***************
*** 469,475 ****
// Using number 0 or 1 for bool is OK.
return OK;
if (give_msg)
! arg_type_mismatch(expected, actual, argidx);
return FAIL;
}
if (expected->tt_type == VAR_DICT || expected->tt_type == VAR_LIST)
--- 492,498 ----
// Using number 0 or 1 for bool is OK.
return OK;
if (give_msg)
! type_mismatch_where(expected, actual, where);
return FAIL;
}
if (expected->tt_type == VAR_DICT || expected->tt_type == VAR_LIST)
***************
*** 477,483 ****
// "unknown" is used for an empty list or dict
if (actual->tt_member != &t_unknown)
ret = check_type(expected->tt_member, actual->tt_member,
! FALSE, 0);
}
else if (expected->tt_type == VAR_FUNC)
{
--- 500,506 ----
// "unknown" is used for an empty list or dict
if (actual->tt_member != &t_unknown)
ret = check_type(expected->tt_member, actual->tt_member,
! FALSE, where);
}
else if (expected->tt_type == VAR_FUNC)
{
***************
*** 486,492 ****
if (expected->tt_member != &t_unknown
&& actual->tt_member != &t_unknown)
ret = check_type(expected->tt_member, actual->tt_member,
! FALSE, 0);
if (ret == OK && expected->tt_argcount != -1
&& actual->tt_argcount != -1
&& (actual->tt_argcount < expected->tt_min_argcount
--- 509,515 ----
if (expected->tt_member != &t_unknown
&& actual->tt_member != &t_unknown)
ret = check_type(expected->tt_member, actual->tt_member,
! FALSE, where);
if (ret == OK && expected->tt_argcount != -1
&& actual->tt_argcount != -1
&& (actual->tt_argcount < expected->tt_min_argcount
***************
*** 500,507 ****
for (i = 0; i < expected->tt_argcount; ++i)
// Allow for using "any" argument type, lambda's have them.
if (actual->tt_args[i] != &t_any && check_type(
! expected->tt_args[i], actual->tt_args[i], FALSE, 0)
! == FAIL)
{
ret = FAIL;
break;
--- 523,530 ----
for (i = 0; i < expected->tt_argcount; ++i)
// Allow for using "any" argument type, lambda's have them.
if (actual->tt_args[i] != &t_any && check_type(
! expected->tt_args[i], actual->tt_args[i], FALSE,
! where) == FAIL)
{
ret = FAIL;
break;
***************
*** 509,515 ****
}
}
if (ret == FAIL && give_msg)
! arg_type_mismatch(expected, actual, argidx);
}
return ret;
}
--- 532,538 ----
}
}
if (ret == FAIL && give_msg)
! type_mismatch_where(expected, actual, where);
}
return ret;
}
***************
*** 552,558 ****
expected = type->tt_args[type->tt_argcount - 1]->tt_member;
else
expected = type->tt_args[i];
! if (check_typval_type(expected, &argvars[i], i + 1) == FAIL)
return FAIL;
}
return OK;
--- 575,581 ----
expected = type->tt_args[type->tt_argcount - 1]->tt_member;
else
expected = type->tt_args[i];
! if (check_typval_arg_type(expected, &argvars[i], i + 1) == FAIL)
return FAIL;
}
return OK;
*** ../vim-8.2.2500/src/proto/vim9type.pro 2021-01-16 16:06:58.126713782
+0100
--- src/proto/vim9type.pro 2021-02-11 20:57:26.463773355 +0100
***************
*** 11,20 ****
int need_convert_to_bool(type_T *type, typval_T *tv);
type_T *typval2type(typval_T *tv, garray_T *type_gap);
type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap);
! int check_typval_type(type_T *expected, typval_T *actual_tv, int argidx);
void type_mismatch(type_T *expected, type_T *actual);
! void arg_type_mismatch(type_T *expected, type_T *actual, int argidx);
! int check_type(type_T *expected, type_T *actual, int give_msg, int argidx);
int check_argument_types(type_T *type, typval_T *argvars, int argcount,
char_u *name);
char_u *skip_type(char_u *start, int optional);
type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error);
--- 11,22 ----
int need_convert_to_bool(type_T *type, typval_T *tv);
type_T *typval2type(typval_T *tv, garray_T *type_gap);
type_T *typval2type_vimvar(typval_T *tv, garray_T *type_gap);
! int check_typval_arg_type(type_T *expected, typval_T *actual_tv, int arg_idx);
! int check_typval_type(type_T *expected, typval_T *actual_tv, where_T where);
void type_mismatch(type_T *expected, type_T *actual);
! void arg_type_mismatch(type_T *expected, type_T *actual, int arg_idx);
! void type_mismatch_where(type_T *expected, type_T *actual, where_T where);
! int check_type(type_T *expected, type_T *actual, int give_msg, where_T where);
int check_argument_types(type_T *type, typval_T *argvars, int argcount,
char_u *name);
char_u *skip_type(char_u *start, int optional);
type_T *parse_type(char_u **arg, garray_T *type_gap, int give_error);
*** ../vim-8.2.2500/src/errors.h 2021-02-10 22:23:36.398613504 +0100
--- src/errors.h 2021-02-11 19:56:36.101245373 +0100
***************
*** 361,363 ****
--- 361,365 ----
INIT(= N_("E1161: Cannot json encode a %s"));
EXTERN char e_register_name_must_be_one_char_str[]
INIT(= N_("E1162: Register name must be one character: %s"));
+ EXTERN char e_variable_nr_type_mismatch_expected_str_but_got_str[]
+ INIT(= N_("E1163: Variable %d: type mismatch, expected %s but got %s"));
*** ../vim-8.2.2500/src/evalvars.c 2021-01-23 13:39:10.395533599 +0100
--- src/evalvars.c 2021-02-11 20:45:13.374442236 +0100
***************
*** 173,179 ****
static void list_win_vars(int *first);
static void list_tab_vars(int *first);
static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first);
! static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags,
char_u *endchars, char_u *op);
static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep,
void *cookie);
static int do_lock_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep,
void *cookie);
static void list_one_var(dictitem_T *v, char *prefix, int *first);
--- 173,179 ----
static void list_win_vars(int *first);
static void list_tab_vars(int *first);
static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first);
! static char_u *ex_let_one(char_u *arg, typval_T *tv, int copy, int flags,
char_u *endchars, char_u *op, int var_idx);
static int do_unlet_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep,
void *cookie);
static int do_lock_var(lval_T *lp, char_u *name_end, exarg_T *eap, int deep,
void *cookie);
static void list_one_var(dictitem_T *v, char *prefix, int *first);
***************
*** 929,941 ****
char_u *arg = arg_start;
list_T *l;
int i;
listitem_T *item;
typval_T ltv;
if (*arg != '[')
{
// ":let var = expr" or ":for var in list"
! if (ex_let_one(arg, tv, copy, flags, op, op) == NULL)
return FAIL;
return OK;
}
--- 929,942 ----
char_u *arg = arg_start;
list_T *l;
int i;
+ int var_idx = 0;
listitem_T *item;
typval_T ltv;
if (*arg != '[')
{
// ":let var = expr" or ":for var in list"
! if (ex_let_one(arg, tv, copy, flags, op, op, var_idx) == NULL)
return FAIL;
return OK;
}
***************
*** 964,970 ****
while (*arg != ']')
{
arg = skipwhite(arg + 1);
! arg = ex_let_one(arg, &item->li_tv, TRUE, flags, (char_u *)",;]", op);
item = item->li_next;
if (arg == NULL)
return FAIL;
--- 965,973 ----
while (*arg != ']')
{
arg = skipwhite(arg + 1);
! ++var_idx;
! arg = ex_let_one(arg, &item->li_tv, TRUE, flags, (char_u *)",;]",
! op, var_idx);
item = item->li_next;
if (arg == NULL)
return FAIL;
***************
*** 987,995 ****
ltv.v_lock = 0;
ltv.vval.v_list = l;
l->lv_refcount = 1;
arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, flags,
! (char_u *)"]", op);
clear_tv(<v);
if (arg == NULL)
return FAIL;
--- 990,999 ----
ltv.v_lock = 0;
ltv.vval.v_list = l;
l->lv_refcount = 1;
+ ++var_idx;
arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, flags,
! (char_u *)"]", op, var_idx);
clear_tv(<v);
if (arg == NULL)
return FAIL;
***************
*** 1284,1290 ****
int copy, // copy value from "tv"
int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc.
char_u *endchars, // valid chars after variable name or NULL
! char_u *op) // "+", "-", "." or NULL
{
int c1;
char_u *name;
--- 1288,1295 ----
int copy, // copy value from "tv"
int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc.
char_u *endchars, // valid chars after variable name or NULL
! char_u *op, // "+", "-", "." or NULL
! int var_idx) // variable index for "let [a, b] =
list"
{
int c1;
char_u *name;
***************
*** 1508,1514 ****
emsg(_(e_letunexp));
else
{
! set_var_lval(&lv, p, tv, copy, flags, op);
arg_end = p;
}
}
--- 1513,1519 ----
emsg(_(e_letunexp));
else
{
! set_var_lval(&lv, p, tv, copy, flags, op, var_idx);
arg_end = p;
}
}
***************
*** 3075,3081 ****
typval_T *tv,
int copy) // make copy of value in "tv"
{
! set_var_const(name, NULL, tv, copy, ASSIGN_DECL);
}
/*
--- 3080,3086 ----
typval_T *tv,
int copy) // make copy of value in "tv"
{
! set_var_const(name, NULL, tv, copy, ASSIGN_DECL, 0);
}
/*
***************
*** 3089,3095 ****
type_T *type,
typval_T *tv_arg,
int copy, // make copy of value in "tv"
! int flags) // ASSIGN_CONST, ASSIGN_FINAL, etc.
{
typval_T *tv = tv_arg;
typval_T bool_tv;
--- 3094,3101 ----
type_T *type,
typval_T *tv_arg,
int copy, // make copy of value in "tv"
! int flags, // ASSIGN_CONST, ASSIGN_FINAL, etc.
! int var_idx) // index for ":let [a, b] = list"
{
typval_T *tv = tv_arg;
typval_T bool_tv;
***************
*** 3148,3153 ****
--- 3154,3161 ----
if (is_script_local && vim9script)
{
+ where_T where;
+
if ((flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0)
{
semsg(_(e_redefining_script_item_str), name);
***************
*** 3155,3161 ****
}
// check the type and adjust to bool if needed
! if (check_script_var_type(&di->di_tv, tv, name) == FAIL)
goto failed;
}
--- 3163,3171 ----
}
// check the type and adjust to bool if needed
! where.wt_index = var_idx;
! where.wt_variable = TRUE;
! if (check_script_var_type(&di->di_tv, tv, name, where) == FAIL)
goto failed;
}
***************
*** 3719,3728 ****
tv.vval.v_string = (char_u *)"";
if (append)
set_var_lval(redir_lval, redir_endp, &tv, TRUE,
! ASSIGN_NO_DECL, (char_u *)".");
else
set_var_lval(redir_lval, redir_endp, &tv, TRUE,
! ASSIGN_NO_DECL, (char_u *)"=");
clear_lval(redir_lval);
if (called_emsg > called_emsg_before)
{
--- 3729,3738 ----
tv.vval.v_string = (char_u *)"";
if (append)
set_var_lval(redir_lval, redir_endp, &tv, TRUE,
! ASSIGN_NO_DECL, (char_u *)".", 0);
else
set_var_lval(redir_lval, redir_endp, &tv, TRUE,
! ASSIGN_NO_DECL, (char_u *)"=", 0);
clear_lval(redir_lval);
if (called_emsg > called_emsg_before)
{
***************
*** 3794,3800 ****
FALSE, FALSE, 0, FNE_CHECK_START);
if (redir_endp != NULL && redir_lval->ll_name != NULL)
set_var_lval(redir_lval, redir_endp, &tv, FALSE, 0,
! (char_u *)".");
clear_lval(redir_lval);
}
--- 3804,3810 ----
FALSE, FALSE, 0, FNE_CHECK_START);
if (redir_endp != NULL && redir_lval->ll_name != NULL)
set_var_lval(redir_lval, redir_endp, &tv, FALSE, 0,
! (char_u *)".", 0);
clear_lval(redir_lval);
}
*** ../vim-8.2.2500/src/proto/evalvars.pro 2021-01-13 19:48:41.628312470
+0100
--- src/proto/evalvars.pro 2021-02-11 20:53:53.224524973 +0100
***************
*** 70,76 ****
void vars_clear_ext(hashtab_T *ht, int free_val);
void delete_var(hashtab_T *ht, hashitem_T *hi);
void set_var(char_u *name, typval_T *tv, int copy);
! void set_var_const(char_u *name, type_T *type, typval_T *tv_arg, int copy,
int flags);
int var_check_permission(dictitem_T *di, char_u *name);
int var_check_ro(int flags, char_u *name, int use_gettext);
int var_check_lock(int flags, char_u *name, int use_gettext);
--- 70,76 ----
void vars_clear_ext(hashtab_T *ht, int free_val);
void delete_var(hashtab_T *ht, hashitem_T *hi);
void set_var(char_u *name, typval_T *tv, int copy);
! void set_var_const(char_u *name, type_T *type, typval_T *tv_arg, int copy,
int flags, int var_idx);
int var_check_permission(dictitem_T *di, char_u *name);
int var_check_ro(int flags, char_u *name, int use_gettext);
int var_check_lock(int flags, char_u *name, int use_gettext);
*** ../vim-8.2.2500/src/eval.c 2021-02-03 19:51:14.935468638 +0100
--- src/eval.c 2021-02-11 20:50:35.937234567 +0100
***************
*** 1299,1306 ****
char_u *endp,
typval_T *rettv,
int copy,
! int flags, // ASSIGN_CONST, ASSIGN_NO_DECL
! char_u *op)
{
int cc;
listitem_T *ri;
--- 1299,1307 ----
char_u *endp,
typval_T *rettv,
int copy,
! int flags, // ASSIGN_CONST, ASSIGN_NO_DECL
! char_u *op,
! int var_idx) // index for "let [a, b] = list"
{
int cc;
listitem_T *ri;
***************
*** 1390,1398 ****
else
{
if (lp->ll_type != NULL
! && check_typval_type(lp->ll_type, rettv, 0) == FAIL)
return;
! set_var_const(lp->ll_name, lp->ll_type, rettv, copy, flags);
}
*endp = cc;
}
--- 1391,1400 ----
else
{
if (lp->ll_type != NULL
! && check_typval_arg_type(lp->ll_type, rettv, 0) == FAIL)
return;
! set_var_const(lp->ll_name, lp->ll_type, rettv, copy,
! flags, var_idx);
}
*endp = cc;
}
***************
*** 1471,1477 ****
}
if (lp->ll_valtype != NULL
! && check_typval_type(lp->ll_valtype, rettv, 0) == FAIL)
return;
if (lp->ll_newkey != NULL)
--- 1473,1479 ----
}
if (lp->ll_valtype != NULL
! && check_typval_arg_type(lp->ll_valtype, rettv, 0) == FAIL)
return;
if (lp->ll_newkey != NULL)
*** ../vim-8.2.2500/src/proto/eval.pro 2021-01-21 12:34:11.441508288 +0100
--- src/proto/eval.pro 2021-02-11 20:08:36.171007139 +0100
***************
*** 25,31 ****
int eval_foldexpr(char_u *arg, int *cp);
char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int
skip, int flags, int fne_flags);
void clear_lval(lval_T *lp);
! void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, int
flags, char_u *op);
void *eval_for_line(char_u *arg, int *errp, exarg_T *eap, evalarg_T *evalarg);
void skip_for_lines(void *fi_void, evalarg_T *evalarg);
int next_for_item(void *fi_void, char_u *arg);
--- 25,31 ----
int eval_foldexpr(char_u *arg, int *cp);
char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int
skip, int flags, int fne_flags);
void clear_lval(lval_T *lp);
! void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, int
flags, char_u *op, int var_idx);
void *eval_for_line(char_u *arg, int *errp, exarg_T *eap, evalarg_T *evalarg);
void skip_for_lines(void *fi_void, evalarg_T *evalarg);
int next_for_item(void *fi_void, char_u *arg);
*** ../vim-8.2.2500/src/vim9execute.c 2021-02-03 20:01:16.777542349 +0100
--- src/vim9execute.c 2021-02-11 21:18:14.586440583 +0100
***************
*** 851,857 ****
funccal_entry_T entry;
save_funccal(&entry);
! set_var_const(name, NULL, tv, FALSE, ASSIGN_DECL);
restore_funccal();
}
--- 851,857 ----
funccal_entry_T entry;
save_funccal(&entry);
! set_var_const(name, NULL, tv, FALSE, ASSIGN_DECL, 0);
restore_funccal();
}
***************
*** 1146,1151 ****
--- 1146,1152 ----
int save_did_emsg_def = did_emsg_def;
int trylevel_at_start = trylevel;
int orig_funcdepth;
+ where_T where;
// Get pointer to item in the stack.
#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
***************
*** 1202,1208 ****
++idx)
{
if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len
! && check_typval_type(ufunc->uf_arg_types[idx], &argv[idx],
idx + 1) == FAIL)
goto failed_early;
copy_tv(&argv[idx], STACK_TV_BOT(0));
--- 1203,1209 ----
++idx)
{
if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len
! && check_typval_arg_type(ufunc->uf_arg_types[idx], &argv[idx],
idx + 1) == FAIL)
goto failed_early;
copy_tv(&argv[idx], STACK_TV_BOT(0));
***************
*** 1233,1239 ****
for (idx = 0; idx < vararg_count; ++idx)
{
! if (check_typval_type(expected, &li->li_tv,
argc + idx + 1) == FAIL)
goto failed_early;
li = li->li_next;
--- 1234,1240 ----
for (idx = 0; idx < vararg_count; ++idx)
{
! if (check_typval_arg_type(expected, &li->li_tv,
argc + idx + 1) == FAIL)
goto failed_early;
li = li->li_next;
***************
*** 1333,1338 ****
--- 1334,1342 ----
emsg_silent_def = emsg_silent;
did_emsg_def = 0;
+ where.wt_index = 0;
+ where.wt_variable = FALSE;
+
// Decide where to start execution, handles optional arguments.
init_instr_idx(ufunc, argc, &ectx);
***************
*** 3170,3175 ****
--- 3174,3184 ----
goto failed;
++ectx.ec_stack.ga_len;
copy_tv(&li->li_tv, STACK_TV_BOT(-1));
+
+ // Useful when used in unpack assignment. Reset at
+ // ISN_DROP.
+ where.wt_index = index + 1;
+ where.wt_variable = TRUE;
}
break;
***************
*** 3288,3296 ****
tv = STACK_TV_BOT((int)ct->ct_off);
SOURCING_LNUM = iptr->isn_lnum;
! if (check_typval_type(ct->ct_type, tv, ct->ct_arg_idx)
! == FAIL)
goto on_error;
// number 0 is FALSE, number 1 is TRUE
if (tv->v_type == VAR_NUMBER
--- 3297,3308 ----
tv = STACK_TV_BOT((int)ct->ct_off);
SOURCING_LNUM = iptr->isn_lnum;
! if (!where.wt_variable)
! where.wt_index = ct->ct_arg_idx;
! if (check_typval_type(ct->ct_type, tv, where) == FAIL)
goto on_error;
+ if (!where.wt_variable)
+ where.wt_index = 0;
// number 0 is FALSE, number 1 is TRUE
if (tv->v_type == VAR_NUMBER
***************
*** 3573,3578 ****
--- 3585,3592 ----
case ISN_DROP:
--ectx.ec_stack.ga_len;
clear_tv(STACK_TV_BOT(0));
+ where.wt_index = 0;
+ where.wt_variable = FALSE;
break;
}
continue;
*** ../vim-8.2.2500/src/vim9script.c 2021-02-07 15:28:05.792508596 +0100
--- src/vim9script.c 2021-02-11 20:47:20.029959029 +0100
***************
*** 650,656 ****
init_tv.v_type = VAR_NUMBER;
else
init_tv.v_type = type->tt_type;
! set_var_const(name, type, &init_tv, FALSE, 0);
vim_free(name);
return p;
--- 650,656 ----
init_tv.v_type = VAR_NUMBER;
else
init_tv.v_type = type->tt_type;
! set_var_const(name, type, &init_tv, FALSE, 0, 0);
vim_free(name);
return p;
***************
*** 855,861 ****
if (sv->sv_name != NULL && sv->sv_tv == dest)
return sv;
}
! iemsg("check_script_var_type(): not found");
return NULL;
}
--- 855,861 ----
if (sv->sv_name != NULL && sv->sv_tv == dest)
return sv;
}
! iemsg("find_typval_in_script(): not found");
return NULL;
}
***************
*** 864,870 ****
* If needed convert "value" to a bool.
*/
int
! check_script_var_type(typval_T *dest, typval_T *value, char_u *name)
{
svar_T *sv = find_typval_in_script(dest);
int ret;
--- 864,874 ----
* If needed convert "value" to a bool.
*/
int
! check_script_var_type(
! typval_T *dest,
! typval_T *value,
! char_u *name,
! where_T where)
{
svar_T *sv = find_typval_in_script(dest);
int ret;
***************
*** 876,882 ****
semsg(_(e_readonlyvar), name);
return FAIL;
}
! ret = check_typval_type(sv->sv_type, value, 0);
if (ret == OK && need_convert_to_bool(sv->sv_type, value))
{
int val = tv2bool(value);
--- 880,886 ----
semsg(_(e_readonlyvar), name);
return FAIL;
}
! ret = check_typval_type(sv->sv_type, value, where);
if (ret == OK && need_convert_to_bool(sv->sv_type, value))
{
int val = tv2bool(value);
*** ../vim-8.2.2500/src/proto/vim9script.pro 2021-01-11 21:20:05.669652000
+0100
--- src/proto/vim9script.pro 2021-02-11 20:53:00.444713247 +0100
***************
*** 14,18 ****
void hide_script_var(scriptitem_T *si, int idx, int func_defined);
void free_all_script_vars(scriptitem_T *si);
svar_T *find_typval_in_script(typval_T *dest);
! int check_script_var_type(typval_T *dest, typval_T *value, char_u *name);
/* vim: set ft=c : */
--- 14,18 ----
void hide_script_var(scriptitem_T *si, int idx, int func_defined);
void free_all_script_vars(scriptitem_T *si);
svar_T *find_typval_in_script(typval_T *dest);
! int check_script_var_type(typval_T *dest, typval_T *value, char_u *name,
where_T where);
/* vim: set ft=c : */
*** ../vim-8.2.2500/src/dict.c 2021-02-07 18:06:25.266692335 +0100
--- src/dict.c 2021-02-11 20:49:23.173500910 +0100
***************
*** 1089,1095 ****
}
if (type != NULL
! && check_typval_type(type, &HI2DI(hi2)->di_tv, 0) == FAIL)
break;
if (di1 == NULL)
--- 1089,1096 ----
}
if (type != NULL
! && check_typval_arg_type(type, &HI2DI(hi2)->di_tv, 0)
! == FAIL)
break;
if (di1 == NULL)
*** ../vim-8.2.2500/src/list.c 2021-02-07 18:06:25.266692335 +0100
--- src/list.c 2021-02-11 20:51:55.068947950 +0100
***************
*** 698,704 ****
listitem_T *ni;
if (l->lv_type != NULL && l->lv_type->tt_member != NULL
! && check_typval_type(l->lv_type->tt_member, tv, 0) == FAIL)
return FAIL;
ni = listitem_alloc();
if (ni == NULL)
--- 698,704 ----
listitem_T *ni;
if (l->lv_type != NULL && l->lv_type->tt_member != NULL
! && check_typval_arg_type(l->lv_type->tt_member, tv, 0) == FAIL)
return FAIL;
ni = listitem_alloc();
if (ni == NULL)
***************
*** 2135,2142 ****
}
if (filtermap == FILTERMAP_MAP)
{
! if (type != NULL && check_typval_type(type->tt_member,
! &newtv, 0) == FAIL)
{
clear_tv(&newtv);
break;
--- 2135,2142 ----
}
if (filtermap == FILTERMAP_MAP)
{
! if (type != NULL && check_typval_arg_type(
! type->tt_member, &newtv, 0) == FAIL)
{
clear_tv(&newtv);
break;
***************
*** 2270,2277 ****
if (filtermap != FILTERMAP_FILTER)
{
if (filtermap == FILTERMAP_MAP && type != NULL
! && check_typval_type(type->tt_member,
! &newtv, 0) == FAIL)
{
clear_tv(&newtv);
break;
--- 2270,2277 ----
if (filtermap != FILTERMAP_FILTER)
{
if (filtermap == FILTERMAP_MAP && type != NULL
! && check_typval_arg_type(
! type->tt_member, &newtv, 0) == FAIL)
{
clear_tv(&newtv);
break;
***************
*** 2314,2321 ****
}
if (filtermap == FILTERMAP_MAP)
{
! if (type != NULL && check_typval_type(type->tt_member,
! &newtv, 0) == FAIL)
{
clear_tv(&newtv);
break;
--- 2314,2321 ----
}
if (filtermap == FILTERMAP_MAP)
{
! if (type != NULL && check_typval_arg_type(
! type->tt_member, &newtv, 0) == FAIL)
{
clear_tv(&newtv);
break;
***************
*** 2584,2590 ****
}
else
item = NULL;
! if (type != NULL && check_typval_type(type, &argvars[1], 2) == FAIL)
goto theend;
list_extend(l1, l2, item);
--- 2584,2591 ----
}
else
item = NULL;
! if (type != NULL && check_typval_arg_type(
! type, &argvars[1], 2) == FAIL)
goto theend;
list_extend(l1, l2, item);
***************
*** 2641,2647 ****
else
action = (char_u *)"force";
! if (type != NULL && check_typval_type(type, &argvars[1], 2) == FAIL)
goto theend;
dict_extend(d1, d2, action);
--- 2642,2649 ----
else
action = (char_u *)"force";
! if (type != NULL && check_typval_arg_type(
! type, &argvars[1], 2) == FAIL)
goto theend;
dict_extend(d1, d2, action);
*** ../vim-8.2.2500/src/vim9compile.c 2021-02-07 18:06:25.266692335 +0100
--- src/vim9compile.c 2021-02-11 20:57:11.231826641 +0100
***************
*** 893,898 ****
--- 893,900 ----
int silent,
int actual_is_const)
{
+ where_T where;
+
if (expected == &t_bool && actual != &t_bool
&& (actual->tt_flags & TTFLAG_BOOL_OK))
{
***************
*** 902,908 ****
return OK;
}
! if (check_type(expected, actual, FALSE, arg_idx) == OK)
return OK;
// If the actual type can be the expected type add a runtime check.
--- 904,912 ----
return OK;
}
! where.wt_index = arg_idx;
! where.wt_variable = FALSE;
! if (check_type(expected, actual, FALSE, where) == OK)
return OK;
// If the actual type can be the expected type add a runtime check.
***************
*** 4287,4296 ****
{
garray_T *stack = &cctx->ctx_type_stack;
type_T *actual;
generate_ppconst(cctx, ppconst);
actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
! if (check_type(want_type, actual, FALSE, 0) == FAIL)
{
if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
return FAIL;
--- 4291,4303 ----
{
garray_T *stack = &cctx->ctx_type_stack;
type_T *actual;
+ where_T where;
generate_ppconst(cctx, ppconst);
actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
! where.wt_index = 0;
! where.wt_variable = FALSE;
! if (check_type(want_type, actual, FALSE, where) == FAIL)
{
if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
return FAIL;
***************
*** 8078,8083 ****
--- 8085,8091 ----
garray_T *stack = &cctx.ctx_type_stack;
type_T *val_type;
int arg_idx = first_def_arg + i;
+ where_T where;
ufunc->uf_def_arg_idx[i] = instr->ga_len;
arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
***************
*** 8088,8100 ****
// Otherwise check that the default value type matches the
// specified type.
val_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
if (ufunc->uf_arg_types[arg_idx] == &t_unknown)
{
did_set_arg_type = TRUE;
ufunc->uf_arg_types[arg_idx] = val_type;
}
else if (check_type(ufunc->uf_arg_types[arg_idx], val_type,
! TRUE, arg_idx + 1) == FAIL)
goto erret;
if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
--- 8096,8110 ----
// Otherwise check that the default value type matches the
// specified type.
val_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
+ where.wt_index = arg_idx + 1;
+ where.wt_variable = FALSE;
if (ufunc->uf_arg_types[arg_idx] == &t_unknown)
{
did_set_arg_type = TRUE;
ufunc->uf_arg_types[arg_idx] = val_type;
}
else if (check_type(ufunc->uf_arg_types[arg_idx], val_type,
! TRUE, where) == FAIL)
goto erret;
if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL)
*** ../vim-8.2.2500/src/testdir/test_vim9_assign.vim 2021-01-23
13:39:10.395533599 +0100
--- src/testdir/test_vim9_assign.vim 2021-02-11 21:09:37.020541628 +0100
***************
*** 284,289 ****
--- 284,297 ----
[v1, v2] = ''
END
CheckDefFailure(lines, 'E1012: Type mismatch; expected list<any> but got
string', 3)
+
+ lines =<< trim END
+ g:values = [false, 0]
+ var x: bool
+ var y: string
+ [x, y] = g:values
+ END
+ CheckDefExecAndScriptFailure(lines, 'E1163: Variable 2: type mismatch,
expected string but got number')
enddef
def Test_assign_linebreak()
*** ../vim-8.2.2500/src/version.c 2021-02-11 19:18:54.274296667 +0100
--- src/version.c 2021-02-11 21:19:08.686231844 +0100
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 2501,
/**/
--
Some say the world will end in fire; some say in segfaults.
I say it will end in a curly bracket.
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/vim_dev/202102112022.11BKMAjF690652%40masaka.moolenaar.net.