Mercurial > vim
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 */ |