From bd3a9d2c946bae0427d7c9b9249716064935fb4e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 17 May 2022 16:12:39 +0100 Subject: [PATCH] patch 8.2.4973: Vim9: type error for list unpack mentions argument Problem: Vim9: type error for list unpack mentions argument. Solution: Mention variable. (close #10435) --- src/proto/vim9instr.pro | 4 ++-- src/testdir/test_vim9_disassemble.vim | 4 ++-- src/testdir/test_vim9_script.vim | 2 +- src/version.c | 2 ++ src/vim9.h | 1 + src/vim9compile.c | 3 ++- src/vim9execute.c | 10 +++++++--- src/vim9instr.c | 4 +++- 8 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/proto/vim9instr.pro b/src/proto/vim9instr.pro index 76c3f882a..f8d60ad9c 100644 --- a/src/proto/vim9instr.pro +++ b/src/proto/vim9instr.pro @@ -9,9 +9,10 @@ vartype_T operator_type(type_T *type1, type_T *type2); int generate_two_op(cctx_T *cctx, char_u *op); int check_compare_types(exprtype_T type, typval_T *tv1, typval_T *tv2); int generate_COMPARE(cctx_T *cctx, exprtype_T exprtype, int ic); +int generate_CONCAT(cctx_T *cctx, int count); int generate_2BOOL(cctx_T *cctx, int invert, int offset); int generate_COND2BOOL(cctx_T *cctx); -int generate_TYPECHECK(cctx_T *cctx, type_T *expected, int offset, int argidx); +int generate_TYPECHECK(cctx_T *cctx, type_T *expected, int offset, int is_var, int argidx); int generate_SETTYPE(cctx_T *cctx, type_T *expected); int generate_tv_PUSH(cctx_T *cctx, typval_T *tv); int generate_PUSHNR(cctx_T *cctx, varnumber_T number); @@ -62,7 +63,6 @@ int generate_LEGACY_EVAL(cctx_T *cctx, char_u *line); int generate_EXECCONCAT(cctx_T *cctx, int count); int generate_RANGE(cctx_T *cctx, char_u *range); int generate_UNPACK(cctx_T *cctx, int var_count, int semicolon); -int generate_CONCAT(cctx_T *cctx, int count); int generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod); int generate_undo_cmdmods(cctx_T *cctx); int generate_store_var(cctx_T *cctx, assign_dest_T dest, int opt_flags, int vimvaridx, int scriptvar_idx, int scriptvar_sid, type_T *type, char_u *name); diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 3ab3c0d25..c99c8b4fa 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -581,10 +581,10 @@ def Test_disassemble_list_assign() '\d CHECKTYPE list stack\[-1\]\_s*' .. '\d CHECKLEN >= 2\_s*' .. '\d\+ ITEM 0\_s*' .. - '\d\+ CHECKTYPE string stack\[-1\] arg 1\_s*' .. + '\d\+ CHECKTYPE string stack\[-1\] var 1\_s*' .. '\d\+ STORE $0\_s*' .. '\d\+ ITEM 1\_s*' .. - '\d\+ CHECKTYPE string stack\[-1\] arg 2\_s*' .. + '\d\+ CHECKTYPE string stack\[-1\] var 2\_s*' .. '\d\+ STORE $1\_s*' .. '\d\+ SLICE 2\_s*' .. '\d\+ STORE $2\_s*' .. diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 7166b13fb..fc0ef15b8 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -2302,7 +2302,7 @@ def Test_for_loop_fails() echo k v endfor END - v9.CheckDefExecAndScriptFailure(lines, ['E1013: Argument 1: type mismatch, expected job but got string', 'E1012: Type mismatch; expected job but got string'], 2) + v9.CheckDefExecAndScriptFailure(lines, ['E1163: Variable 1: type mismatch, expected job but got string', 'E1012: Type mismatch; expected job but got string'], 2) lines =<< trim END var i = 0 diff --git a/src/version.c b/src/version.c index 873b17bfd..68d11a2b0 100644 --- a/src/version.c +++ b/src/version.c @@ -746,6 +746,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 4973, /**/ 4972, /**/ diff --git a/src/vim9.h b/src/vim9.h index 1b5a58b8c..3ab1c5aa9 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -296,6 +296,7 @@ typedef struct { type_T *ct_type; int8_T ct_off; // offset in stack, -1 is bottom int8_T ct_arg_idx; // argument index or zero + int8_T ct_is_var; // when TRUE checking variable instead of arg } checktype_T; // arguments to ISN_STORENR diff --git a/src/vim9compile.c b/src/vim9compile.c index 3eae14aec..48a913a4b 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -412,7 +412,8 @@ need_type_where( // If the actual type can be the expected type add a runtime check. if (!actual_is_const && ret == MAYBE && use_typecheck(actual, expected)) { - generate_TYPECHECK(cctx, expected, offset, where.wt_index); + generate_TYPECHECK(cctx, expected, offset, + where.wt_variable, where.wt_index); return OK; } diff --git a/src/vim9execute.c b/src/vim9execute.c index 5644f3474..5050df6c1 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -4652,14 +4652,17 @@ exec_instructions(ectx_T *ectx) case ISN_CHECKTYPE: { checktype_T *ct = &iptr->isn_arg.type; + int save_wt_variable = ectx->ec_where.wt_variable; tv = STACK_TV_BOT((int)ct->ct_off); SOURCING_LNUM = iptr->isn_lnum; if (!ectx->ec_where.wt_variable) ectx->ec_where.wt_index = ct->ct_arg_idx; + ectx->ec_where.wt_variable = ct->ct_is_var; if (check_typval_type(ct->ct_type, tv, ectx->ec_where) == FAIL) goto on_error; + ectx->ec_where.wt_variable = save_wt_variable; if (!ectx->ec_where.wt_variable) ectx->ec_where.wt_index = 0; @@ -6114,18 +6117,19 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc) case ISN_CHECKTYPE: { - checktype_T *ct = &iptr->isn_arg.type; - char *tofree; + checktype_T *ct = &iptr->isn_arg.type; + char *tofree; if (ct->ct_arg_idx == 0) smsg("%s%4d CHECKTYPE %s stack[%d]", pfx, current, type_name(ct->ct_type, &tofree), (int)ct->ct_off); else - smsg("%s%4d CHECKTYPE %s stack[%d] arg %d", + smsg("%s%4d CHECKTYPE %s stack[%d] %s %d", pfx, current, type_name(ct->ct_type, &tofree), (int)ct->ct_off, + ct->ct_is_var ? "var": "arg", (int)ct->ct_arg_idx); vim_free(tofree); break; diff --git a/src/vim9instr.c b/src/vim9instr.c index edc5db045..3a8d695da 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -542,6 +542,7 @@ generate_TYPECHECK( cctx_T *cctx, type_T *expected, int offset, + int is_var, int argidx) { isn_T *isn; @@ -551,6 +552,7 @@ generate_TYPECHECK( return FAIL; isn->isn_arg.type.ct_type = alloc_type(expected); isn->isn_arg.type.ct_off = (int8_T)offset; + isn->isn_arg.type.ct_is_var = is_var; isn->isn_arg.type.ct_arg_idx = (int8_T)argidx; // type becomes expected @@ -1437,7 +1439,7 @@ generate_BCALL(cctx_T *cctx, int func_idx, int argcount, int method_call) if (maptype != NULL && maptype[0].type_decl->tt_member != NULL && maptype[0].type_decl->tt_member != &t_any) // Check that map() didn't change the item types. - generate_TYPECHECK(cctx, maptype[0].type_decl, -1, 1); + generate_TYPECHECK(cctx, maptype[0].type_decl, -1, FALSE, 1); return OK; } -- 2.50.0