]> granicus.if.org Git - vim/commitdiff
patch 8.2.4973: Vim9: type error for list unpack mentions argument v8.2.4973
authorBram Moolenaar <Bram@vim.org>
Tue, 17 May 2022 15:12:39 +0000 (16:12 +0100)
committerBram Moolenaar <Bram@vim.org>
Tue, 17 May 2022 15:12:39 +0000 (16:12 +0100)
Problem:    Vim9: type error for list unpack mentions argument.
Solution:   Mention variable. (close #10435)

src/proto/vim9instr.pro
src/testdir/test_vim9_disassemble.vim
src/testdir/test_vim9_script.vim
src/version.c
src/vim9.h
src/vim9compile.c
src/vim9execute.c
src/vim9instr.c

index 76c3f882a5e532f54435174f3c430e9b73354290..f8d60ad9c686792ffc98d091fcf1d5fc646dd307 100644 (file)
@@ -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);
index 3ab3c0d25deeec6864c289cd2de829ad6560f3ea..c99c8b4fa4b7c5a52bf0fc7ecfcfcb51d8fb7985 100644 (file)
@@ -581,10 +581,10 @@ def Test_disassemble_list_assign()
         '\d CHECKTYPE list<any> 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*' ..
index 7166b13fb3b2abbc6213107dff3badc1b9539f38..fc0ef15b885b867a05c371c5456abf3d0023a3ac 100644 (file)
@@ -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
index 873b17bfd96e91ed152677dd0b2a46197ecf62de..68d11a2b0f7f77dfd9bb8bb3f8e9ab1f18b0ccae 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4973,
 /**/
     4972,
 /**/
index 1b5a58b8c3be02e2a4920601e3b94b8c09a4fa4d..3ab1c5aa96d8748e8e30f1062f81a9785694b30b 100644 (file)
@@ -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
index 3eae14aec013dc1dceffa8b601a9444057547121..48a913a4b18095dffb068688b7d01e7a82274e05 100644 (file)
@@ -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;
     }
 
index 5644f3474fb3a895fbd3d24cc4c8c75da509ecf1..5050df6c11c31e95a724c1e072db9dfdd15ec61d 100644 (file)
@@ -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;
index edc5db045110b23299ce7e8b4fce90043f6a100e..3a8d695dad322de6b2ddb2566852d5c9abc4742f 100644 (file)
@@ -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;
 }