diff src/list.c @ 27517:f00a7a2bee21 v8.2.4286

patch 8.2.4286: Vim9: strict type checking after copy() and deepcopy() Commit: https://github.com/vim/vim/commit/381692b6f1c2ec9b73a139500286ddc9347a1c01 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Feb 2 20:01:27 2022 +0000 patch 8.2.4286: Vim9: strict type checking after copy() and deepcopy() Problem: Vim9: strict type checking after copy() and deepcopy(). Solution: Allow type to change after making a copy. (closes https://github.com/vim/vim/issues/9644)
author Bram Moolenaar <Bram@vim.org>
date Wed, 02 Feb 2022 21:15:03 +0100
parents c7f614c9ceb3
children 4ca0ee7b4f86
line wrap: on
line diff
--- a/src/list.c
+++ b/src/list.c
@@ -1015,7 +1015,7 @@ flatten_common(typval_T *argvars, typval
 
     if (make_copy)
     {
-	l = list_copy(l, TRUE, get_copyID());
+	l = list_copy(l, TRUE, TRUE, get_copyID());
 	rettv->vval.v_list = l;
 	if (l == NULL)
 	    return;
@@ -1102,7 +1102,7 @@ list_concat(list_T *l1, list_T *l2, typv
     if (l1 == NULL)
 	l = list_alloc();
     else
-	l = list_copy(l1, FALSE, 0);
+	l = list_copy(l1, FALSE, TRUE, 0);
     if (l == NULL)
 	return FAIL;
     tv->v_type = VAR_LIST;
@@ -1200,11 +1200,11 @@ list_slice_or_index(
 /*
  * Make a copy of list "orig".  Shallow if "deep" is FALSE.
  * The refcount of the new list is set to 1.
- * See item_copy() for "copyID".
+ * See item_copy() for "top" and "copyID".
  * Returns NULL when out of memory.
  */
     list_T *
-list_copy(list_T *orig, int deep, int copyID)
+list_copy(list_T *orig, int deep, int top, int copyID)
 {
     list_T	*copy;
     listitem_T	*item;
@@ -1216,7 +1216,7 @@ list_copy(list_T *orig, int deep, int co
     copy = list_alloc();
     if (copy != NULL)
     {
-	copy->lv_type = alloc_type(orig->lv_type);
+	copy->lv_type = alloc_type(top || deep ? &t_list_any: orig->lv_type);
 	if (copyID != 0)
 	{
 	    // Do this before adding the items, because one of the items may
@@ -1233,7 +1233,8 @@ list_copy(list_T *orig, int deep, int co
 		break;
 	    if (deep)
 	    {
-		if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL)
+		if (item_copy(&item->li_tv, &ni->li_tv,
+						  deep, FALSE, copyID) == FAIL)
 		{
 		    vim_free(ni);
 		    break;
@@ -2701,11 +2702,11 @@ list_extend_func(
     }
     l2 = argvars[1].vval.v_list;
     if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE))
-	    && l2 != NULL)
+								 && l2 != NULL)
     {
 	if (is_new)
 	{
-	    l1 = list_copy(l1, FALSE, get_copyID());
+	    l1 = list_copy(l1, FALSE, TRUE, get_copyID());
 	    if (l1 == NULL)
 		return;
 	}