diff options
-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; |