Mercurial > vim
changeset 23199:59f31d2eb4cf v8.2.2145
patch 8.2.2145: Vim9: concatenating lists does not adjust type of result
Commit: https://github.com/vim/vim/commit/399ea8108c8da3fcdf5d738a0f8eae67155b4b10
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Dec 15 21:28:57 2020 +0100
patch 8.2.2145: Vim9: concatenating lists does not adjust type of result
Problem: Vim9: concatenating lists does not adjust type of result.
Solution: When list member types differ use "any" member type.
(closes #7473)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 15 Dec 2020 21:30:04 +0100 |
parents | e7fe2f43809c |
children | f26564daf7a8 |
files | src/testdir/test_vim9_expr.vim src/version.c src/vim9compile.c |
diffstat | 3 files changed, 35 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -1317,6 +1317,23 @@ func Test_expr5_fails_channel() call CheckDefFailure(["var x = 'a' .. test_null_channel()"], 'E1105:', 1) endfunc +def Test_expr5_list_add() + # concatenating two lists with same member types is OK + var d = {} + for i in ['a'] + ['b'] + d = {[i]: 0} + endfor + + # concatenating two lists with different member types results in "any" + var lines =<< trim END + var d = {} + for i in ['a'] + [0] + d = {[i]: 0} + endfor + END + CheckDefExecFailure(lines, 'E1012:') +enddef + " test multiply, divide, modulo def Test_expr6() var lines =<< trim END
--- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2145, +/**/ 2144, /**/ 2143,
--- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -538,14 +538,15 @@ generate_add_instr( type_T *type1, type_T *type2) { - isn_T *isn = generate_instr_drop(cctx, - vartype == VAR_NUMBER ? ISN_OPNR - : vartype == VAR_LIST ? ISN_ADDLIST - : vartype == VAR_BLOB ? ISN_ADDBLOB + garray_T *stack = &cctx->ctx_type_stack; + isn_T *isn = generate_instr_drop(cctx, + vartype == VAR_NUMBER ? ISN_OPNR + : vartype == VAR_LIST ? ISN_ADDLIST + : vartype == VAR_BLOB ? ISN_ADDBLOB #ifdef FEAT_FLOAT - : vartype == VAR_FLOAT ? ISN_OPFLOAT + : vartype == VAR_FLOAT ? ISN_OPFLOAT #endif - : ISN_OPANY, 1); + : ISN_OPANY, 1); if (vartype != VAR_LIST && vartype != VAR_BLOB && type1->tt_type != VAR_ANY @@ -556,6 +557,14 @@ generate_add_instr( if (isn != NULL) isn->isn_arg.op.op_type = EXPR_ADD; + + // When concatenating two lists with different member types the member type + // becomes "any". + if (vartype == VAR_LIST + && type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST + && type1->tt_member != type2->tt_member) + (((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any; + return isn == NULL ? FAIL : OK; } @@ -7172,6 +7181,7 @@ compile_put(char_u *arg, exarg_T *eap, c // Either no range or a number. // "errormsg" will not be set because the range is ADDR_LINES. if (parse_cmd_address(eap, &errormsg, FALSE) == FAIL) + // cannot happen return NULL; if (eap->addr_count == 0) lnum = -1;