0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 8.2.1176: Vim9: not enough type checking in Vim9 script

Problem:    Vim9: not enough type checking in Vim9 script.
Solution:   Use same type checking as in a :def function.
This commit is contained in:
Bram Moolenaar
2020-07-10 22:45:38 +02:00
parent 7ff78465f7
commit 543e6f3467
5 changed files with 41 additions and 3 deletions

View File

@@ -2460,8 +2460,16 @@ eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
} }
if (evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE)) if (evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE))
{ {
int ret = typval_compare(rettv, &var2, type, ic); int ret;
if (in_vim9script() && check_compare_types(
type, rettv, &var2) == FAIL)
{
ret = FAIL;
clear_tv(rettv);
}
else
ret = typval_compare(rettv, &var2, type, ic);
clear_tv(&var2); clear_tv(&var2);
return ret; return ret;
} }

View File

@@ -3,6 +3,7 @@ int check_defined(char_u *p, size_t len, cctx_T *cctx);
void clear_type_list(garray_T *gap); void clear_type_list(garray_T *gap);
type_T *typval2type(typval_T *tv); type_T *typval2type(typval_T *tv);
int check_type(type_T *expected, type_T *actual, int give_msg); int check_type(type_T *expected, type_T *actual, int give_msg);
int check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2);
char_u *skip_type(char_u *start); char_u *skip_type(char_u *start);
type_T *parse_type(char_u **arg, garray_T *type_gap); type_T *parse_type(char_u **arg, garray_T *type_gap);
char *vartype_name(vartype_T type); char *vartype_name(vartype_T type);

View File

@@ -557,7 +557,7 @@ def RetVoid()
enddef enddef
def Test_expr4_vimscript() def Test_expr4_vimscript()
" only checks line continuation " check line continuation
let lines =<< trim END let lines =<< trim END
vim9script vim9script
let var = 0 let var = 0
@@ -599,6 +599,25 @@ def Test_expr4_vimscript()
assert_equal(1, var) assert_equal(1, var)
END END
CheckScriptSuccess(lines) CheckScriptSuccess(lines)
" spot check mismatching types
lines =<< trim END
vim9script
echo '' == 0
END
CheckScriptFailure(lines, 'E1072:')
lines =<< trim END
vim9script
echo v:true > v:false
END
CheckScriptFailure(lines, 'Cannot compare bool with bool')
lines =<< trim END
vim9script
echo 123 is 123
END
CheckScriptFailure(lines, 'Cannot use "is" with number')
enddef enddef
func Test_expr4_fails() func Test_expr4_fails()

View File

@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1176,
/**/ /**/
1175, 1175,
/**/ /**/

View File

@@ -820,6 +820,14 @@ get_compare_isn(exptype_T exptype, vartype_T type1, vartype_T type2)
return isntype; return isntype;
} }
int
check_compare_types(exptype_T type, typval_T *tv1, typval_T *tv2)
{
if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP)
return FAIL;
return OK;
}
/* /*
* Generate an ISN_COMPARE* instruction with a boolean result. * Generate an ISN_COMPARE* instruction with a boolean result.
*/ */
@@ -4296,7 +4304,7 @@ compile_expr4(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
// Both sides are a constant, compute the result now. // Both sides are a constant, compute the result now.
// First check for a valid combination of types, this is more // First check for a valid combination of types, this is more
// strict than typval_compare(). // strict than typval_compare().
if (get_compare_isn(type, tv1->v_type, tv2->v_type) == ISN_DROP) if (check_compare_types(type, tv1, tv2) == FAIL)
ret = FAIL; ret = FAIL;
else else
{ {