@@ -254,7 +254,7 @@ func_type_add_arg_types(
254254 * "type_gap" is used to temporarily create types in.
255255 */
256256 static type_T *
257- typval2type_int (typval_T * tv , garray_T * type_gap )
257+ typval2type_int (typval_T * tv , int copyID , garray_T * type_gap )
258258{
259259 type_T * type ;
260260 type_T * member_type = & t_any ;
@@ -276,11 +276,15 @@ typval2type_int(typval_T *tv, garray_T *type_gap)
276276 return & t_list_empty ;
277277 if (l -> lv_first == & range_list_item )
278278 return & t_list_number ;
279+ if (l -> lv_copyID == copyID )
280+ // avoid recursion
281+ return & t_list_any ;
282+ l -> lv_copyID = copyID ;
279283
280284 // Use the common type of all members.
281- member_type = typval2type (& l -> lv_first -> li_tv , type_gap );
285+ member_type = typval2type (& l -> lv_first -> li_tv , copyID , type_gap );
282286 for (li = l -> lv_first -> li_next ; li != NULL ; li = li -> li_next )
283- common_type (typval2type (& li -> li_tv , type_gap ),
287+ common_type (typval2type (& li -> li_tv , copyID , type_gap ),
284288 member_type , & member_type , type_gap );
285289 return get_list_type (member_type , type_gap );
286290 }
@@ -289,17 +293,21 @@ typval2type_int(typval_T *tv, garray_T *type_gap)
289293 {
290294 dict_iterator_T iter ;
291295 typval_T * value ;
296+ dict_T * d = tv -> vval .v_dict ;
292297
293- if (tv -> vval .v_dict == NULL
294- || tv -> vval .v_dict -> dv_hashtab .ht_used == 0 )
298+ if (d == NULL || d -> dv_hashtab .ht_used == 0 )
295299 return & t_dict_empty ;
300+ if (d -> dv_copyID == copyID )
301+ // avoid recursion
302+ return & t_dict_any ;
303+ d -> dv_copyID = copyID ;
296304
297305 // Use the common type of all values.
298306 dict_iterate_start (tv , & iter );
299307 dict_iterate_next (& iter , & value );
300- member_type = typval2type (value , type_gap );
308+ member_type = typval2type (value , copyID , type_gap );
301309 while (dict_iterate_next (& iter , & value ) != NULL )
302- common_type (typval2type (value , type_gap ),
310+ common_type (typval2type (value , copyID , type_gap ),
303311 member_type , & member_type , type_gap );
304312 return get_dict_type (member_type , type_gap );
305313 }
@@ -372,9 +380,9 @@ need_convert_to_bool(type_T *type, typval_T *tv)
372380 * "type_list" is used to temporarily create types in.
373381 */
374382 type_T *
375- typval2type (typval_T * tv , garray_T * type_gap )
383+ typval2type (typval_T * tv , int copyID , garray_T * type_gap )
376384{
377- type_T * type = typval2type_int (tv , type_gap );
385+ type_T * type = typval2type_int (tv , copyID , type_gap );
378386
379387 if (type != NULL && type != & t_bool
380388 && (tv -> v_type == VAR_NUMBER
@@ -396,7 +404,7 @@ typval2type_vimvar(typval_T *tv, garray_T *type_gap)
396404 return & t_list_string ;
397405 if (tv -> v_type == VAR_DICT ) // e.g. for v:completed_item
398406 return & t_dict_any ;
399- return typval2type (tv , type_gap );
407+ return typval2type (tv , get_copyID (), type_gap );
400408}
401409
402410 int
@@ -421,7 +429,7 @@ check_typval_type(type_T *expected, typval_T *actual_tv, where_T where)
421429 int res = FAIL ;
422430
423431 ga_init2 (& type_list , sizeof (type_T * ), 10 );
424- actual_type = typval2type (actual_tv , & type_list );
432+ actual_type = typval2type (actual_tv , get_copyID (), & type_list );
425433 if (actual_type != NULL )
426434 res = check_type (expected , actual_type , TRUE, where );
427435 clear_type_list (& type_list );
@@ -1202,7 +1210,7 @@ f_typename(typval_T *argvars, typval_T *rettv)
12021210
12031211 rettv -> v_type = VAR_STRING ;
12041212 ga_init2 (& type_list , sizeof (type_T * ), 10 );
1205- type = typval2type (argvars , & type_list );
1213+ type = typval2type (argvars , get_copyID (), & type_list );
12061214 name = type_name (type , & tofree );
12071215 if (tofree != NULL )
12081216 rettv -> vval .v_string = (char_u * )tofree ;
0 commit comments