Mercurial > vim
comparison 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 |
comparison
equal
deleted
inserted
replaced
27516:fdcbdd530e4c | 27517:f00a7a2bee21 |
---|---|
1013 if (l == NULL) | 1013 if (l == NULL) |
1014 return; | 1014 return; |
1015 | 1015 |
1016 if (make_copy) | 1016 if (make_copy) |
1017 { | 1017 { |
1018 l = list_copy(l, TRUE, get_copyID()); | 1018 l = list_copy(l, TRUE, TRUE, get_copyID()); |
1019 rettv->vval.v_list = l; | 1019 rettv->vval.v_list = l; |
1020 if (l == NULL) | 1020 if (l == NULL) |
1021 return; | 1021 return; |
1022 // The type will change. | 1022 // The type will change. |
1023 free_type(l->lv_type); | 1023 free_type(l->lv_type); |
1100 | 1100 |
1101 // make a copy of the first list. | 1101 // make a copy of the first list. |
1102 if (l1 == NULL) | 1102 if (l1 == NULL) |
1103 l = list_alloc(); | 1103 l = list_alloc(); |
1104 else | 1104 else |
1105 l = list_copy(l1, FALSE, 0); | 1105 l = list_copy(l1, FALSE, TRUE, 0); |
1106 if (l == NULL) | 1106 if (l == NULL) |
1107 return FAIL; | 1107 return FAIL; |
1108 tv->v_type = VAR_LIST; | 1108 tv->v_type = VAR_LIST; |
1109 tv->v_lock = 0; | 1109 tv->v_lock = 0; |
1110 tv->vval.v_list = l; | 1110 tv->vval.v_list = l; |
1198 } | 1198 } |
1199 | 1199 |
1200 /* | 1200 /* |
1201 * Make a copy of list "orig". Shallow if "deep" is FALSE. | 1201 * Make a copy of list "orig". Shallow if "deep" is FALSE. |
1202 * The refcount of the new list is set to 1. | 1202 * The refcount of the new list is set to 1. |
1203 * See item_copy() for "copyID". | 1203 * See item_copy() for "top" and "copyID". |
1204 * Returns NULL when out of memory. | 1204 * Returns NULL when out of memory. |
1205 */ | 1205 */ |
1206 list_T * | 1206 list_T * |
1207 list_copy(list_T *orig, int deep, int copyID) | 1207 list_copy(list_T *orig, int deep, int top, int copyID) |
1208 { | 1208 { |
1209 list_T *copy; | 1209 list_T *copy; |
1210 listitem_T *item; | 1210 listitem_T *item; |
1211 listitem_T *ni; | 1211 listitem_T *ni; |
1212 | 1212 |
1214 return NULL; | 1214 return NULL; |
1215 | 1215 |
1216 copy = list_alloc(); | 1216 copy = list_alloc(); |
1217 if (copy != NULL) | 1217 if (copy != NULL) |
1218 { | 1218 { |
1219 copy->lv_type = alloc_type(orig->lv_type); | 1219 copy->lv_type = alloc_type(top || deep ? &t_list_any: orig->lv_type); |
1220 if (copyID != 0) | 1220 if (copyID != 0) |
1221 { | 1221 { |
1222 // Do this before adding the items, because one of the items may | 1222 // Do this before adding the items, because one of the items may |
1223 // refer back to this list. | 1223 // refer back to this list. |
1224 orig->lv_copyID = copyID; | 1224 orig->lv_copyID = copyID; |
1231 ni = listitem_alloc(); | 1231 ni = listitem_alloc(); |
1232 if (ni == NULL) | 1232 if (ni == NULL) |
1233 break; | 1233 break; |
1234 if (deep) | 1234 if (deep) |
1235 { | 1235 { |
1236 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) | 1236 if (item_copy(&item->li_tv, &ni->li_tv, |
1237 deep, FALSE, copyID) == FAIL) | |
1237 { | 1238 { |
1238 vim_free(ni); | 1239 vim_free(ni); |
1239 break; | 1240 break; |
1240 } | 1241 } |
1241 } | 1242 } |
2699 emsg(_(e_cannot_extend_null_list)); | 2700 emsg(_(e_cannot_extend_null_list)); |
2700 return; | 2701 return; |
2701 } | 2702 } |
2702 l2 = argvars[1].vval.v_list; | 2703 l2 = argvars[1].vval.v_list; |
2703 if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE)) | 2704 if ((is_new || !value_check_lock(l1->lv_lock, arg_errmsg, TRUE)) |
2704 && l2 != NULL) | 2705 && l2 != NULL) |
2705 { | 2706 { |
2706 if (is_new) | 2707 if (is_new) |
2707 { | 2708 { |
2708 l1 = list_copy(l1, FALSE, get_copyID()); | 2709 l1 = list_copy(l1, FALSE, TRUE, get_copyID()); |
2709 if (l1 == NULL) | 2710 if (l1 == NULL) |
2710 return; | 2711 return; |
2711 } | 2712 } |
2712 | 2713 |
2713 if (argvars[2].v_type != VAR_UNKNOWN) | 2714 if (argvars[2].v_type != VAR_UNKNOWN) |