summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-07-18 14:43:43 +0200
committerBram Moolenaar <Bram@vim.org>2021-07-18 14:43:43 +0200
commit0c35752d04f70408a3c560d5b3edbafcaddff302 (patch)
treef4db397f3be18ba9dc6082b73ed24e98affb15da
parentc6ba2f9dde6d01c8ab356c239c2259f7d83652a4 (diff)
patch 8.2.3176: Vim9: no type error for comparing number with stringv8.2.3176
Problem: Vim9: no type error for comparing number with string. Solution: Add a runtime type check. (closes #8571)
-rw-r--r--src/errors.h4
-rw-r--r--src/testdir/test_vim9_expr.vim23
-rw-r--r--src/typval.c16
-rw-r--r--src/version.c2
4 files changed, 41 insertions, 4 deletions
diff --git a/src/errors.h b/src/errors.h
index 46de733bc6..35d1487338 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -381,8 +381,8 @@ EXTERN char e_mismatched_endfunction[]
INIT(= N_("E1151: Mismatched endfunction"));
EXTERN char e_mismatched_enddef[]
INIT(= N_("E1152: Mismatched enddef"));
-EXTERN char e_invalid_operation_for_bool[]
- INIT(= N_("E1153: Invalid operation for bool"));
+EXTERN char e_invalid_operation_for_str[]
+ INIT(= N_("E1153: Invalid operation for %s"));
EXTERN char e_divide_by_zero[]
INIT(= N_("E1154: Divide by zero"));
EXTERN char e_cannot_define_autocommands_for_all_events[]
diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index cd6ffa4463..e7c08f4af0 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -660,13 +660,36 @@ def Test_expr4_equal()
CheckDefExecAndScriptFailure(["var x: any = true", 'echo x == ""'], 'E1072: Cannot compare bool with string', 2)
CheckDefExecAndScriptFailure2(["var x: any = 99", 'echo x == true'], 'E1138', 'E1072:', 2)
CheckDefExecAndScriptFailure2(["var x: any = 'a'", 'echo x == 99'], 'E1030:', 'E1072:', 2)
+enddef
+def Test_expr4_wrong_type()
for op in ['>', '>=', '<', '<=', '=~', '!~']
CheckDefExecAndScriptFailure([
"var a: any = 'a'",
'var b: any = true',
'echo a ' .. op .. ' b'], 'E1072:', 3)
endfor
+ for op in ['>', '>=', '<', '<=']
+ CheckDefExecAndScriptFailure2([
+ "var n: any = 2",
+ 'echo n ' .. op .. ' "3"'], 'E1030:', 'E1072:', 2)
+ endfor
+ for op in ['=~', '!~']
+ CheckDefExecAndScriptFailure([
+ "var n: any = 2",
+ 'echo n ' .. op .. ' "3"'], 'E1072:', 2)
+ endfor
+
+ CheckDefAndScriptFailure([
+ 'echo v:none == true'], 'E1072:', 1)
+ CheckDefAndScriptFailure([
+ 'echo false >= true'], 'E1072:', 1)
+ CheckDefExecAndScriptFailure([
+ "var n: any = v:none",
+ 'echo n == true'], 'E1072:', 2)
+ CheckDefExecAndScriptFailure([
+ "var n: any = v:none",
+ 'echo n < true'], 'E1072:', 2)
enddef
" test != comperator
diff --git a/src/typval.c b/src/typval.c
index 03891c806d..9d5903f649 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -937,7 +937,9 @@ typval_compare(
}
}
else if (in_vim9script() && (typ1->v_type == VAR_BOOL
- || typ2->v_type == VAR_BOOL))
+ || typ2->v_type == VAR_BOOL
+ || (typ1->v_type == VAR_SPECIAL
+ && typ2->v_type == VAR_SPECIAL)))
{
if (typ1->v_type != typ2->v_type)
{
@@ -955,13 +957,23 @@ typval_compare(
case EXPR_ISNOT:
case EXPR_NEQUAL: n1 = (n1 != n2); break;
default:
- emsg(_(e_invalid_operation_for_bool));
+ semsg(_(e_invalid_operation_for_str),
+ vartype_name(typ1->v_type));
clear_tv(typ1);
return FAIL;
}
}
else
{
+ if (in_vim9script()
+ && ((typ1->v_type != VAR_STRING && typ1->v_type != VAR_SPECIAL)
+ || (typ2->v_type != VAR_STRING && typ2->v_type != VAR_SPECIAL)))
+ {
+ semsg(_(e_cannot_compare_str_with_str),
+ vartype_name(typ1->v_type), vartype_name(typ2->v_type));
+ clear_tv(typ1);
+ return FAIL;
+ }
s1 = tv_get_string_buf(typ1, buf1);
s2 = tv_get_string_buf(typ2, buf2);
if (type != EXPR_MATCH && type != EXPR_NOMATCH)
diff --git a/src/version.c b/src/version.c
index 8b674d3773..c1a4f3f8fa 100644
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 3176,
+/**/
3175,
/**/
3174,