1
0
forked from aniani/vim

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)
This commit is contained in:
Bram Moolenaar 2020-12-15 21:28:57 +01:00
parent 025cb1ca86
commit 399ea8108c
3 changed files with 35 additions and 6 deletions

View File

@ -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

View File

@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2145,
/**/
2144,
/**/

View File

@ -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;