diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-12-15 21:28:57 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-12-15 21:28:57 +0100 |
commit | 399ea8108c8da3fcdf5d738a0f8eae67155b4b10 (patch) | |
tree | 028ca323c9db0b5a8ed501f44246aa58c76d2268 | |
parent | 025cb1ca8605055383c53bf2c823d7093cf29b82 (diff) | |
download | vim-git-399ea8108c8da3fcdf5d738a0f8eae67155b4b10.tar.gz |
patch 8.2.2145: Vim9: concatenating lists does not adjust type of resultv8.2.2145
Problem: Vim9: concatenating lists does not adjust type of result.
Solution: When list member types differ use "any" member type.
(closes #7473)
-rw-r--r-- | src/testdir/test_vim9_expr.vim | 17 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 22 |
3 files changed, 35 insertions, 6 deletions
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index 812aabf99..9147536a6 100644 --- 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 diff --git a/src/version.c b/src/version.c index dfd565126..aeac2652e 100644 --- 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, diff --git a/src/vim9compile.c b/src/vim9compile.c index 86d3260d9..2db226c8d 100644 --- 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, cctx_T *cctx) // 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; |