changeset 28901:11609f025219 v8.2.4973

patch 8.2.4973: Vim9: type error for list unpack mentions argument Commit: https://github.com/vim/vim/commit/bd3a9d2c946bae0427d7c9b9249716064935fb4e Author: Bram Moolenaar <Bram@vim.org> Date: Tue May 17 16:12:39 2022 +0100 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 https://github.com/vim/vim/issues/10435)
author Bram Moolenaar <Bram@vim.org>
date Tue, 17 May 2022 17:15:03 +0200
parents 7630685d3e43
children 26d0d6f9b368
files 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
diffstat 8 files changed, 20 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/proto/vim9instr.pro
+++ b/src/proto/vim9instr.pro
@@ -9,9 +9,10 @@ vartype_T operator_type(type_T *type1, t
 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, c
 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);
--- 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<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*' ..
--- 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
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4973,
+/**/
     4972,
 /**/
     4971,
--- 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
--- 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;
     }
 
--- 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 *inst
 
 	    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;
--- 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_id
     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;
 }