Skip to content

Commit 0c35752

Browse files
committed
patch 8.2.3176: Vim9: no type error for comparing number with string
Problem: Vim9: no type error for comparing number with string. Solution: Add a runtime type check. (closes #8571)
1 parent c6ba2f9 commit 0c35752

4 files changed

Lines changed: 41 additions & 4 deletions

File tree

src/errors.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ EXTERN char e_mismatched_endfunction[]
381381
INIT(= N_("E1151: Mismatched endfunction"));
382382
EXTERN char e_mismatched_enddef[]
383383
INIT(= N_("E1152: Mismatched enddef"));
384-
EXTERN char e_invalid_operation_for_bool[]
385-
INIT(= N_("E1153: Invalid operation for bool"));
384+
EXTERN char e_invalid_operation_for_str[]
385+
INIT(= N_("E1153: Invalid operation for %s"));
386386
EXTERN char e_divide_by_zero[]
387387
INIT(= N_("E1154: Divide by zero"));
388388
EXTERN char e_cannot_define_autocommands_for_all_events[]

src/testdir/test_vim9_expr.vim

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,13 +660,36 @@ def Test_expr4_equal()
660660
CheckDefExecAndScriptFailure(["var x: any = true", 'echo x == ""'], 'E1072: Cannot compare bool with string', 2)
661661
CheckDefExecAndScriptFailure2(["var x: any = 99", 'echo x == true'], 'E1138', 'E1072:', 2)
662662
CheckDefExecAndScriptFailure2(["var x: any = 'a'", 'echo x == 99'], 'E1030:', 'E1072:', 2)
663+
enddef
663664

665+
def Test_expr4_wrong_type()
664666
for op in ['>', '>=', '<', '<=', '=~', '!~']
665667
CheckDefExecAndScriptFailure([
666668
"var a: any = 'a'",
667669
'var b: any = true',
668670
'echo a ' .. op .. ' b'], 'E1072:', 3)
669671
endfor
672+
for op in ['>', '>=', '<', '<=']
673+
CheckDefExecAndScriptFailure2([
674+
"var n: any = 2",
675+
'echo n ' .. op .. ' "3"'], 'E1030:', 'E1072:', 2)
676+
endfor
677+
for op in ['=~', '!~']
678+
CheckDefExecAndScriptFailure([
679+
"var n: any = 2",
680+
'echo n ' .. op .. ' "3"'], 'E1072:', 2)
681+
endfor
682+
683+
CheckDefAndScriptFailure([
684+
'echo v:none == true'], 'E1072:', 1)
685+
CheckDefAndScriptFailure([
686+
'echo false >= true'], 'E1072:', 1)
687+
CheckDefExecAndScriptFailure([
688+
"var n: any = v:none",
689+
'echo n == true'], 'E1072:', 2)
690+
CheckDefExecAndScriptFailure([
691+
"var n: any = v:none",
692+
'echo n < true'], 'E1072:', 2)
670693
enddef
671694

672695
" test != comperator

src/typval.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,9 @@ typval_compare(
937937
}
938938
}
939939
else if (in_vim9script() && (typ1->v_type == VAR_BOOL
940-
|| typ2->v_type == VAR_BOOL))
940+
|| typ2->v_type == VAR_BOOL
941+
|| (typ1->v_type == VAR_SPECIAL
942+
&& typ2->v_type == VAR_SPECIAL)))
941943
{
942944
if (typ1->v_type != typ2->v_type)
943945
{
@@ -955,13 +957,23 @@ typval_compare(
955957
case EXPR_ISNOT:
956958
case EXPR_NEQUAL: n1 = (n1 != n2); break;
957959
default:
958-
emsg(_(e_invalid_operation_for_bool));
960+
semsg(_(e_invalid_operation_for_str),
961+
vartype_name(typ1->v_type));
959962
clear_tv(typ1);
960963
return FAIL;
961964
}
962965
}
963966
else
964967
{
968+
if (in_vim9script()
969+
&& ((typ1->v_type != VAR_STRING && typ1->v_type != VAR_SPECIAL)
970+
|| (typ2->v_type != VAR_STRING && typ2->v_type != VAR_SPECIAL)))
971+
{
972+
semsg(_(e_cannot_compare_str_with_str),
973+
vartype_name(typ1->v_type), vartype_name(typ2->v_type));
974+
clear_tv(typ1);
975+
return FAIL;
976+
}
965977
s1 = tv_get_string_buf(typ1, buf1);
966978
s2 = tv_get_string_buf(typ2, buf2);
967979
if (type != EXPR_MATCH && type != EXPR_NOMATCH)

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,8 @@ static char *(features[]) =
755755

756756
static int included_patches[] =
757757
{ /* Add new patch number below this line */
758+
/**/
759+
3176,
758760
/**/
759761
3175,
760762
/**/

0 commit comments

Comments
 (0)