diff src/dict.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 c9474ae175f4
children 2397b18d6f94
line wrap: on
line diff
--- a/src/dict.c
+++ b/src/dict.c
@@ -284,11 +284,11 @@ dictitem_free(dictitem_T *item)
 /*
  * Make a copy of dict "d".  Shallow if "deep" is FALSE.
  * The refcount of the new dict is set to 1.
- * See item_copy() for "copyID".
+ * See item_copy() for "top" and "copyID".
  * Returns NULL when out of memory.
  */
     dict_T *
-dict_copy(dict_T *orig, int deep, int copyID)
+dict_copy(dict_T *orig, int deep, int top, int copyID)
 {
     dict_T	*copy;
     dictitem_T	*di;
@@ -306,6 +306,8 @@ dict_copy(dict_T *orig, int deep, int co
 	    orig->dv_copyID = copyID;
 	    orig->dv_copydict = copy;
 	}
+	copy->dv_type = alloc_type(top || deep ? &t_dict_any : orig->dv_type);
+
 	todo = (int)orig->dv_hashtab.ht_used;
 	for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi)
 	{
@@ -318,8 +320,8 @@ dict_copy(dict_T *orig, int deep, int co
 		    break;
 		if (deep)
 		{
-		    if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep,
-							      copyID) == FAIL)
+		    if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv,
+						  deep, FALSE, copyID) == FAIL)
 		    {
 			vim_free(di);
 			break;
@@ -1239,7 +1241,7 @@ dict_extend_func(
     {
 	if (is_new)
 	{
-	    d1 = dict_copy(d1, FALSE, get_copyID());
+	    d1 = dict_copy(d1, FALSE, TRUE, get_copyID());
 	    if (d1 == NULL)
 		return;
 	}