diff src/vim9compile.c @ 23640:8dcb2255ff9a v8.2.2362

patch 8.2.2362: Vim9: check of builtin function argument type is incomplete Commit: https://github.com/vim/vim/commit/351ead09dd365ebdee2bfa27ab22542d4920c779 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Jan 16 16:07:01 2021 +0100 patch 8.2.2362: Vim9: check of builtin function argument type is incomplete Problem: Vim9: check of builtin function argument type is incomplete. Solution: Use need_type() instead of check_arg_type().
author Bram Moolenaar <Bram@vim.org>
date Sat, 16 Jan 2021 16:15:04 +0100
parents 455ad460ff4f
children c8f26523d7d7
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -878,11 +878,12 @@ use_typecheck(type_T *actual, type_T *ex
  * If "actual_is_const" is TRUE then the type won't change at runtime, do not
  * generate a TYPECHECK.
  */
-    static int
+    int
 need_type(
 	type_T	*actual,
 	type_T	*expected,
 	int	offset,
+	int	arg_idx,
 	cctx_T	*cctx,
 	int	silent,
 	int	actual_is_const)
@@ -896,7 +897,7 @@ need_type(
 	return OK;
     }
 
-    if (check_type(expected, actual, FALSE, 0) == OK)
+    if (check_type(expected, actual, FALSE, arg_idx) == OK)
 	return OK;
 
     // If the actual type can be the expected type add a runtime check.
@@ -908,7 +909,7 @@ need_type(
     }
 
     if (!silent)
-	type_mismatch(expected, actual);
+	arg_type_mismatch(expected, actual, arg_idx);
     return FAIL;
 }
 
@@ -931,7 +932,7 @@ bool_on_stack(cctx_T *cctx)
 	// This requires a runtime type check.
 	return generate_COND2BOOL(cctx);
 
-    return need_type(type, &t_bool, -1, cctx, FALSE, FALSE);
+    return need_type(type, &t_bool, -1, 0, cctx, FALSE, FALSE);
 }
 
 /*
@@ -1613,7 +1614,8 @@ generate_BCALL(cctx_T *cctx, int func_id
     {
 	// Check the types of the arguments.
 	argtypes = ((type_T **)stack->ga_data) + stack->ga_len - argcount;
-	if (internal_func_check_arg_types(argtypes, func_idx, argcount) == FAIL)
+	if (internal_func_check_arg_types(argtypes, func_idx, argcount,
+								 cctx) == FAIL)
 	    return FAIL;
 	if (internal_func_is_map(func_idx))
 	    maptype = *argtypes;
@@ -1656,7 +1658,7 @@ generate_LISTAPPEND(cctx_T *cctx)
     list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2];
     item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
     expected = list_type->tt_member;
-    if (need_type(item_type, expected, -1, cctx, FALSE, FALSE) == FAIL)
+    if (need_type(item_type, expected, -1, 0, cctx, FALSE, FALSE) == FAIL)
 	return FAIL;
 
     if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
@@ -1678,7 +1680,7 @@ generate_BLOBAPPEND(cctx_T *cctx)
 
     // Caller already checked that blob_type is a blob.
     item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    if (need_type(item_type, &t_number, -1, cctx, FALSE, FALSE) == FAIL)
+    if (need_type(item_type, &t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
 	return FAIL;
 
     if (generate_instr(cctx, ISN_BLOBAPPEND) == NULL)
@@ -1733,7 +1735,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufu
 	    else
 		expected = ufunc->uf_va_type->tt_member;
 	    actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i];
-	    if (need_type(actual, expected, -argcount + i, cctx,
+	    if (need_type(actual, expected, -argcount + i, 0, cctx,
 							  TRUE, FALSE) == FAIL)
 	    {
 		arg_type_mismatch(expected, actual, i + 1);
@@ -1850,7 +1852,7 @@ generate_PCALL(
 					     type->tt_argcount - 1]->tt_member;
 		    else
 			expected = type->tt_args[i];
-		    if (need_type(actual, expected, offset,
+		    if (need_type(actual, expected, offset, 0,
 						    cctx, TRUE, FALSE) == FAIL)
 		    {
 			arg_type_mismatch(expected, actual, i + 1);
@@ -3135,7 +3137,7 @@ compile_dict(char_u **arg, cctx_T *cctx,
 	    {
 		type_T *keytype = ((type_T **)stack->ga_data)
 						       [stack->ga_len - 1];
-		if (need_type(keytype, &t_string, -1, cctx,
+		if (need_type(keytype, &t_string, -1, 0, cctx,
 						     FALSE, FALSE) == FAIL)
 		    return FAIL;
 	    }
@@ -3808,13 +3810,13 @@ compile_subscript(
 		vtype = VAR_DICT;
 	    if (vtype == VAR_STRING || vtype == VAR_LIST || vtype == VAR_BLOB)
 	    {
-		if (need_type(valtype, &t_number, -1, cctx,
+		if (need_type(valtype, &t_number, -1, 0, cctx,
 							 FALSE, FALSE) == FAIL)
 		    return FAIL;
 		if (is_slice)
 		{
 		    valtype = ((type_T **)stack->ga_data)[stack->ga_len - 2];
-		    if (need_type(valtype, &t_number, -2, cctx,
+		    if (need_type(valtype, &t_number, -2, 0, cctx,
 							 FALSE, FALSE) == FAIL)
 			return FAIL;
 		}
@@ -3836,7 +3838,7 @@ compile_subscript(
 		}
 		else
 		{
-		    if (need_type(*typep, &t_dict_any, -2, cctx,
+		    if (need_type(*typep, &t_dict_any, -2, 0, cctx,
 							 FALSE, FALSE) == FAIL)
 			return FAIL;
 		    *typep = &t_any;
@@ -4235,7 +4237,7 @@ compile_expr7t(char_u **arg, cctx_T *cct
 	actual = ((type_T **)stack->ga_data)[stack->ga_len - 1];
 	if (check_type(want_type, actual, FALSE, 0) == FAIL)
 	{
-	    if (need_type(actual, want_type, -1, cctx, FALSE, FALSE) == FAIL)
+	    if (need_type(actual, want_type, -1, 0, cctx, FALSE, FALSE) == FAIL)
 		return FAIL;
 	}
     }
@@ -4917,7 +4919,7 @@ compile_return(char_u *arg, int check_re
 		    return NULL;
 		}
 		if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1,
-						   cctx, FALSE, FALSE) == FAIL)
+						0, cctx, FALSE, FALSE) == FAIL)
 		    return NULL;
 	    }
 	}
@@ -5831,7 +5833,7 @@ compile_assign_unlet(
 		  : ((type_T **)stack->ga_data)[stack->ga_len - 1];
 	// now we can properly check the type
 	if (lhs->lhs_type->tt_member != NULL && rhs_type != &t_void
-		&& need_type(rhs_type, lhs->lhs_type->tt_member, -2, cctx,
+		&& need_type(rhs_type, lhs->lhs_type->tt_member, -2, 0, cctx,
 							 FALSE, FALSE) == FAIL)
 	    return FAIL;
     }
@@ -5976,7 +5978,7 @@ compile_assignment(char_u *arg, exarg_T 
 		emsg(_(e_cannot_use_void_value));
 		goto theend;
 	    }
-	    if (need_type(stacktype, &t_list_any, -1, cctx,
+	    if (need_type(stacktype, &t_list_any, -1, 0, cctx,
 							 FALSE, FALSE) == FAIL)
 		goto theend;
 	    // TODO: check the length of a constant list here
@@ -6123,13 +6125,13 @@ compile_assignment(char_u *arg, exarg_T 
 			// without operator check type here, otherwise below
 			if (lhs.lhs_has_index)
 			    use_type = lhs.lhs_member_type;
-			if (need_type(rhs_type, use_type, -1, cctx,
+			if (need_type(rhs_type, use_type, -1, 0, cctx,
 						      FALSE, is_const) == FAIL)
 			    goto theend;
 		    }
 		}
 		else if (*p != '=' && need_type(rhs_type, lhs.lhs_member_type,
-					       -1, cctx, FALSE, FALSE) == FAIL)
+					    -1, 0, cctx, FALSE, FALSE) == FAIL)
 		    goto theend;
 	    }
 	    else if (cmdidx == CMD_final)
@@ -6216,7 +6218,7 @@ compile_assignment(char_u *arg, exarg_T 
 		// If variable is float operation with number is OK.
 		!(expected == &t_float && stacktype == &t_number) &&
 #endif
-		    need_type(stacktype, expected, -1, cctx,
+		    need_type(stacktype, expected, -1, 0, cctx,
 							 FALSE, FALSE) == FAIL)
 		goto theend;
 
@@ -6925,7 +6927,7 @@ compile_for(char_u *arg_start, cctx_T *c
     // Now that we know the type of "var", check that it is a list, now or at
     // runtime.
     vartype = ((type_T **)stack->ga_data)[stack->ga_len - 1];
-    if (need_type(vartype, &t_list_any, -1, cctx, FALSE, FALSE) == FAIL)
+    if (need_type(vartype, &t_list_any, -1, 0, cctx, FALSE, FALSE) == FAIL)
     {
 	drop_scope(cctx);
 	return NULL;