# HG changeset patch # User Bram Moolenaar # Date 1626612304 -7200 # Node ID 55c85c3a43a090018cfd3ff04ddd33029ae972b5 # Parent df8e28f6b0e14f3247c366380cace4250b9b7824 patch 8.2.3176: Vim9: no type error for comparing number with string Commit: https://github.com/vim/vim/commit/0c35752d04f70408a3c560d5b3edbafcaddff302 Author: Bram Moolenaar Date: Sun Jul 18 14:43:43 2021 +0200 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 https://github.com/vim/vim/issues/8571) diff --git a/src/errors.h b/src/errors.h --- 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 --- 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 --- 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 --- 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,