diff src/vim9compile.c @ 25591:ea69398b40d1 v8.2.3332

patch 8.2.3332: Vim9: cannot assign to range in list Commit: https://github.com/vim/vim/commit/4f0884d6e24d1d45ec83fd86b372b403177d3298 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Aug 11 21:49:23 2021 +0200 patch 8.2.3332: Vim9: cannot assign to range in list Problem: Vim9: cannot assign to range in list. Solution: Implement overwriting a list range.
author Bram Moolenaar <Bram@vim.org>
date Wed, 11 Aug 2021 22:00:06 +0200
parents d8fb5bb88362
children c4e29355cd8b
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -6485,6 +6485,29 @@ compile_assign_lhs(
 }
 
 /*
+ * Return TRUE if "lhs" has a range index: "[expr : expr]".
+ */
+    static int
+has_list_index(char_u *idx_start, cctx_T *cctx)
+{
+    char_u  *p = idx_start;
+    int	    save_skip;
+
+    if (*p != '[')
+	return FALSE;
+
+    p = skipwhite(p + 1);
+    if (*p == ':')
+	return TRUE;
+
+    save_skip = cctx->ctx_skip;
+    cctx->ctx_skip = SKIP_YES;
+    (void)compile_expr0(&p, cctx);
+    cctx->ctx_skip = save_skip;
+    return *skipwhite(p) == ':';
+}
+
+/*
  * For an assignment with an index, compile the "idx" in "var[idx]" or "key" in
  * "var.key".
  */
@@ -6652,8 +6675,10 @@ compile_assign_unlet(
 
     if (compile_assign_index(var_start, lhs, &range, cctx) == FAIL)
 	return FAIL;
-    if (is_assign && range && lhs->lhs_type != &t_blob
-						    && lhs->lhs_type != &t_any)
+    if (is_assign && range
+	    && lhs->lhs_type->tt_type != VAR_LIST
+	    && lhs->lhs_type != &t_blob
+	    && lhs->lhs_type != &t_any)
     {
 	semsg(_(e_cannot_use_range_with_assignment_str), var_start);
 	return FAIL;
@@ -7029,7 +7054,11 @@ compile_assignment(char_u *arg, exarg_T 
 			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 assigning to a list or dict member, use the
+			// member type.  Not for "list[:] =".
+			if (lhs.lhs_has_index
+				&& !has_list_index(var_start + lhs.lhs_varlen,
+									 cctx))
 			    use_type = lhs.lhs_member_type;
 			if (need_type_where(rhs_type, use_type, -1, where,
 				    cctx, FALSE, is_const) == FAIL)