diff src/evalvars.c @ 23917:4b417b776b95 v8.2.2501

patch 8.2.2501: not always clear where an error is reported Commit: https://github.com/vim/vim/commit/f785aa1354208f6b644e891aa01f8f86d947af7e Author: Bram Moolenaar <Bram@vim.org> Date: Thu Feb 11 21:19:34 2021 +0100 patch 8.2.2501: not always clear where an error is reported Problem: Not always clear where an error is reported. Solution: Add the where_T structure and pass it around. (closes https://github.com/vim/vim/issues/7796)
author Bram Moolenaar <Bram@vim.org>
date Thu, 11 Feb 2021 21:30:04 +0100
parents 6e8a4a30d94d
children da1c89e61b04
line wrap: on
line diff
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -173,7 +173,7 @@ static void list_buf_vars(int *first);
 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 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,13 +929,14 @@ ex_let_vars(
     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) == NULL)
+	if (ex_let_one(arg, tv, copy, flags, op, op, var_idx) == NULL)
 	    return FAIL;
 	return OK;
     }
@@ -964,7 +965,9 @@ ex_let_vars(
     while (*arg != ']')
     {
 	arg = skipwhite(arg + 1);
-	arg = ex_let_one(arg, &item->li_tv, TRUE, flags, (char_u *)",;]", op);
+	++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,9 +990,10 @@ ex_let_vars(
 	    ltv.v_lock = 0;
 	    ltv.vval.v_list = l;
 	    l->lv_refcount = 1;
+	    ++var_idx;
 
 	    arg = ex_let_one(skipwhite(arg + 1), &ltv, FALSE, flags,
-							    (char_u *)"]", op);
+						   (char_u *)"]", op, var_idx);
 	    clear_tv(&ltv);
 	    if (arg == NULL)
 		return FAIL;
@@ -1284,7 +1288,8 @@ ex_let_one(
     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
+    char_u	*op,		// "+", "-", "."  or NULL
+    int		var_idx)	// variable index for "let [a, b] = list"
 {
     int		c1;
     char_u	*name;
@@ -1508,7 +1513,7 @@ ex_let_one(
 		emsg(_(e_letunexp));
 	    else
 	    {
-		set_var_lval(&lv, p, tv, copy, flags, op);
+		set_var_lval(&lv, p, tv, copy, flags, op, var_idx);
 		arg_end = p;
 	    }
 	}
@@ -3075,7 +3080,7 @@ set_var(
     typval_T	*tv,
     int		copy)	    // make copy of value in "tv"
 {
-    set_var_const(name, NULL, tv, copy, ASSIGN_DECL);
+    set_var_const(name, NULL, tv, copy, ASSIGN_DECL, 0);
 }
 
 /*
@@ -3089,7 +3094,8 @@ set_var_const(
     type_T	*type,
     typval_T	*tv_arg,
     int		copy,	    // make copy of value in "tv"
-    int		flags)	    // ASSIGN_CONST, ASSIGN_FINAL, etc.
+    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,6 +3154,8 @@ set_var_const(
 
 	    if (is_script_local && vim9script)
 	    {
+		where_T where;
+
 		if ((flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0)
 		{
 		    semsg(_(e_redefining_script_item_str), name);
@@ -3155,7 +3163,9 @@ set_var_const(
 		}
 
 		// check the type and adjust to bool if needed
-		if (check_script_var_type(&di->di_tv, tv, name) == FAIL)
+		where.wt_index = var_idx;
+		where.wt_variable = TRUE;
+		if (check_script_var_type(&di->di_tv, tv, name, where) == FAIL)
 		    goto failed;
 	    }
 
@@ -3719,10 +3729,10 @@ var_redir_start(char_u *name, int append
     tv.vval.v_string = (char_u *)"";
     if (append)
 	set_var_lval(redir_lval, redir_endp, &tv, TRUE,
-						ASSIGN_NO_DECL, (char_u *)".");
+					     ASSIGN_NO_DECL, (char_u *)".", 0);
     else
 	set_var_lval(redir_lval, redir_endp, &tv, TRUE,
-						ASSIGN_NO_DECL, (char_u *)"=");
+					     ASSIGN_NO_DECL, (char_u *)"=", 0);
     clear_lval(redir_lval);
     if (called_emsg > called_emsg_before)
     {
@@ -3794,7 +3804,7 @@ var_redir_stop(void)
 					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 *)".");
+							     (char_u *)".", 0);
 	    clear_lval(redir_lval);
 	}