comparison src/list.c @ 27406:4c1bdee75bed v8.2.4231

patch 8.2.4231: Vim9: map() gives type error when type was not declared Commit: https://github.com/vim/vim/commit/35c807df1f5774f09612d756ddc3cd5c44eacaca Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jan 27 16:36:29 2022 +0000 patch 8.2.4231: Vim9: map() gives type error when type was not declared Problem: Vim9: map() gives type error when type was not declared. Solution: Only check the type when it was declared, like extend() does. (closes #9635)
author Bram Moolenaar <Bram@vim.org>
date Thu, 27 Jan 2022 17:45:03 +0100
parents c9474ae175f4
children ec54436eda32
comparison
equal deleted inserted replaced
27405:9265a363d1ab 27406:4c1bdee75bed
578 CHECK_LIST_MATERIALIZE(l); 578 CHECK_LIST_MATERIALIZE(l);
579 if (l->lv_u.mat.lv_last == NULL) 579 if (l->lv_u.mat.lv_last == NULL)
580 { 580 {
581 // empty list 581 // empty list
582 l->lv_first = item; 582 l->lv_first = item;
583 l->lv_u.mat.lv_last = item;
584 item->li_prev = NULL; 583 item->li_prev = NULL;
585 } 584 }
586 else 585 else
587 { 586 {
588 l->lv_u.mat.lv_last->li_next = item; 587 l->lv_u.mat.lv_last->li_next = item;
589 item->li_prev = l->lv_u.mat.lv_last; 588 item->li_prev = l->lv_u.mat.lv_last;
590 l->lv_u.mat.lv_last = item; 589 }
591 } 590 l->lv_u.mat.lv_last = item;
592 ++l->lv_len; 591 ++l->lv_len;
593 item->li_next = NULL; 592 item->li_next = NULL;
594 } 593 }
595 594
596 /* 595 /*
2360 2359
2361 tv.v_type = VAR_NUMBER; 2360 tv.v_type = VAR_NUMBER;
2362 tv.v_lock = 0; 2361 tv.v_lock = 0;
2363 tv.vval.v_number = val; 2362 tv.vval.v_number = val;
2364 set_vim_var_nr(VV_KEY, idx); 2363 set_vim_var_nr(VV_KEY, idx);
2365 if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) 2364 if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL)
2366 == FAIL)
2367 break; 2365 break;
2368 if (did_emsg) 2366 if (did_emsg)
2369 { 2367 {
2370 clear_tv(&newtv); 2368 clear_tv(&newtv);
2371 break; 2369 break;
2459 : filtermap == FILTERMAP_MAPNEW 2457 : filtermap == FILTERMAP_MAPNEW
2460 ? N_("mapnew() argument") 2458 ? N_("mapnew() argument")
2461 : N_("filter() argument")); 2459 : N_("filter() argument"));
2462 int save_did_emsg; 2460 int save_did_emsg;
2463 type_T *type = NULL; 2461 type_T *type = NULL;
2464 garray_T type_list;
2465 2462
2466 // map() and filter() return the first argument, also on failure. 2463 // map() and filter() return the first argument, also on failure.
2467 if (filtermap != FILTERMAP_MAPNEW && argvars[0].v_type != VAR_STRING) 2464 if (filtermap != FILTERMAP_MAPNEW && argvars[0].v_type != VAR_STRING)
2468 copy_tv(&argvars[0], rettv); 2465 copy_tv(&argvars[0], rettv);
2469 2466
2472 == FAIL)) 2469 == FAIL))
2473 return; 2470 return;
2474 2471
2475 if (filtermap == FILTERMAP_MAP && in_vim9script()) 2472 if (filtermap == FILTERMAP_MAP && in_vim9script())
2476 { 2473 {
2477 // Check that map() does not change the type of the dict. 2474 // Check that map() does not change the declared type of the list or
2478 ga_init2(&type_list, sizeof(type_T *), 10); 2475 // dict.
2479 type = typval2type(argvars, get_copyID(), &type_list, TVTT_DO_MEMBER); 2476 if (argvars[0].v_type == VAR_DICT && argvars[0].vval.v_dict != NULL)
2477 type = argvars[0].vval.v_dict->dv_type;
2478 else if (argvars[0].v_type == VAR_LIST
2479 && argvars[0].vval.v_list != NULL)
2480 type = argvars[0].vval.v_list->lv_type;
2480 } 2481 }
2481 2482
2482 if (argvars[0].v_type != VAR_BLOB 2483 if (argvars[0].v_type != VAR_BLOB
2483 && argvars[0].v_type != VAR_LIST 2484 && argvars[0].v_type != VAR_LIST
2484 && argvars[0].v_type != VAR_DICT 2485 && argvars[0].v_type != VAR_DICT
2487 semsg(_(e_argument_of_str_must_be_list_string_dictionary_or_blob), 2488 semsg(_(e_argument_of_str_must_be_list_string_dictionary_or_blob),
2488 func_name); 2489 func_name);
2489 goto theend; 2490 goto theend;
2490 } 2491 }
2491 2492
2492 expr = &argvars[1];
2493 // On type errors, the preceding call has already displayed an error 2493 // On type errors, the preceding call has already displayed an error
2494 // message. Avoid a misleading error message for an empty string that 2494 // message. Avoid a misleading error message for an empty string that
2495 // was not passed as argument. 2495 // was not passed as argument.
2496 expr = &argvars[1];
2496 if (expr->v_type != VAR_UNKNOWN) 2497 if (expr->v_type != VAR_UNKNOWN)
2497 { 2498 {
2498 typval_T save_val; 2499 typval_T save_val;
2499 typval_T save_key; 2500 typval_T save_key;
2500 2501
2523 2524
2524 did_emsg |= save_did_emsg; 2525 did_emsg |= save_did_emsg;
2525 } 2526 }
2526 2527
2527 theend: 2528 theend:
2528 if (type != NULL)
2529 clear_type_list(&type_list);
2530 } 2529 }
2531 2530
2532 /* 2531 /*
2533 * "filter()" function 2532 * "filter()" function
2534 */ 2533 */