Skip to content

Commit 399ea81

Browse files
committed
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)
1 parent 025cb1c commit 399ea81

3 files changed

Lines changed: 35 additions & 6 deletions

File tree

src/testdir/test_vim9_expr.vim

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1317,6 +1317,23 @@ func Test_expr5_fails_channel()
13171317
call CheckDefFailure(["var x = 'a' .. test_null_channel()"], 'E1105:', 1)
13181318
endfunc
13191319

1320+
def Test_expr5_list_add()
1321+
# concatenating two lists with same member types is OK
1322+
var d = {}
1323+
for i in ['a'] + ['b']
1324+
d = {[i]: 0}
1325+
endfor
1326+
1327+
# concatenating two lists with different member types results in "any"
1328+
var lines =<< trim END
1329+
var d = {}
1330+
for i in ['a'] + [0]
1331+
d = {[i]: 0}
1332+
endfor
1333+
END
1334+
CheckDefExecFailure(lines, 'E1012:')
1335+
enddef
1336+
13201337
" test multiply, divide, modulo
13211338
def Test_expr6()
13221339
var lines =<< trim END

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2145,
753755
/**/
754756
2144,
755757
/**/

src/vim9compile.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -538,14 +538,15 @@ generate_add_instr(
538538
type_T *type1,
539539
type_T *type2)
540540
{
541-
isn_T *isn = generate_instr_drop(cctx,
542-
vartype == VAR_NUMBER ? ISN_OPNR
543-
: vartype == VAR_LIST ? ISN_ADDLIST
544-
: vartype == VAR_BLOB ? ISN_ADDBLOB
541+
garray_T *stack = &cctx->ctx_type_stack;
542+
isn_T *isn = generate_instr_drop(cctx,
543+
vartype == VAR_NUMBER ? ISN_OPNR
544+
: vartype == VAR_LIST ? ISN_ADDLIST
545+
: vartype == VAR_BLOB ? ISN_ADDBLOB
545546
#ifdef FEAT_FLOAT
546-
: vartype == VAR_FLOAT ? ISN_OPFLOAT
547+
: vartype == VAR_FLOAT ? ISN_OPFLOAT
547548
#endif
548-
: ISN_OPANY, 1);
549+
: ISN_OPANY, 1);
549550

550551
if (vartype != VAR_LIST && vartype != VAR_BLOB
551552
&& type1->tt_type != VAR_ANY
@@ -556,6 +557,14 @@ generate_add_instr(
556557

557558
if (isn != NULL)
558559
isn->isn_arg.op.op_type = EXPR_ADD;
560+
561+
// When concatenating two lists with different member types the member type
562+
// becomes "any".
563+
if (vartype == VAR_LIST
564+
&& type1->tt_type == VAR_LIST && type2->tt_type == VAR_LIST
565+
&& type1->tt_member != type2->tt_member)
566+
(((type_T **)stack->ga_data)[stack->ga_len - 1]) = &t_list_any;
567+
559568
return isn == NULL ? FAIL : OK;
560569
}
561570

@@ -7172,6 +7181,7 @@ compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
71727181
// Either no range or a number.
71737182
// "errormsg" will not be set because the range is ADDR_LINES.
71747183
if (parse_cmd_address(eap, &errormsg, FALSE) == FAIL)
7184+
// cannot happen
71757185
return NULL;
71767186
if (eap->addr_count == 0)
71777187
lnum = -1;

0 commit comments

Comments
 (0)