From 8cc79e4299ef314d93419ed65bf26aa42af610b2 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 20 Apr 2022 16:00:59 +0800 Subject: [PATCH] checker: check error for arguments of array.contains() (#14102) --- vlib/v/checker/fn.v | 11 ++++++ .../checker/tests/array_contains_args_err.out | 35 +++++++++++++++++++ .../checker/tests/array_contains_args_err.vv | 9 +++++ 3 files changed, 55 insertions(+) create mode 100644 vlib/v/checker/tests/array_contains_args_err.out create mode 100644 vlib/v/checker/tests/array_contains_args_err.vv diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 9b53b8e0b4..2f3dd00789 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1893,6 +1893,17 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as node.return_type = ast.void_type } else if method_name == 'contains' { // c.warn('use `value in arr` instead of `arr.contains(value)`', node.pos) + if node.args.len != 1 { + c.error('`.contains()` expected 1 argument, but got $node.args.len', node.pos) + } else { + arg_typ := ast.mktyp(c.expr(node.args[0].expr)) + elem_typ_str := c.table.type_to_str(elem_typ) + arg_typ_str := c.table.type_to_str(arg_typ) + if !left_sym.has_method('contains') && elem_typ_str != arg_typ_str { + c.error('`.contains()` expected `$elem_typ_str` argument, but got `$arg_typ_str`', + node.pos) + } + } node.return_type = ast.bool_type } else if method_name == 'index' { node.return_type = ast.int_type diff --git a/vlib/v/checker/tests/array_contains_args_err.out b/vlib/v/checker/tests/array_contains_args_err.out new file mode 100644 index 0000000000..10a6c6c567 --- /dev/null +++ b/vlib/v/checker/tests/array_contains_args_err.out @@ -0,0 +1,35 @@ +vlib/v/checker/tests/array_contains_args_err.vv:3:17: error: `.contains()` expected `int` argument, but got `[]int` + 1 | fn main() { + 2 | arr := [0] + 3 | mut ret := [0].contains([0]) + | ~~~~~~~~~~~~~ + 4 | ret = [0].contains() + 5 | ret = [0, 1, 2].contains(0, 1, 2) +vlib/v/checker/tests/array_contains_args_err.vv:4:12: error: `.contains()` expected 1 argument, but got 0 + 2 | arr := [0] + 3 | mut ret := [0].contains([0]) + 4 | ret = [0].contains() + | ~~~~~~~~~~ + 5 | ret = [0, 1, 2].contains(0, 1, 2) + 6 | ret = [0].contains('a') +vlib/v/checker/tests/array_contains_args_err.vv:5:18: error: `.contains()` expected 1 argument, but got 3 + 3 | mut ret := [0].contains([0]) + 4 | ret = [0].contains() + 5 | ret = [0, 1, 2].contains(0, 1, 2) + | ~~~~~~~~~~~~~~~~~ + 6 | ret = [0].contains('a') + 7 | ret = [0].contains(arr) +vlib/v/checker/tests/array_contains_args_err.vv:6:12: error: `.contains()` expected `int` argument, but got `string` + 4 | ret = [0].contains() + 5 | ret = [0, 1, 2].contains(0, 1, 2) + 6 | ret = [0].contains('a') + | ~~~~~~~~~~~~~ + 7 | ret = [0].contains(arr) + 8 | println(ret) +vlib/v/checker/tests/array_contains_args_err.vv:7:12: error: `.contains()` expected `int` argument, but got `[]int` + 5 | ret = [0, 1, 2].contains(0, 1, 2) + 6 | ret = [0].contains('a') + 7 | ret = [0].contains(arr) + | ~~~~~~~~~~~~~ + 8 | println(ret) + 9 | } diff --git a/vlib/v/checker/tests/array_contains_args_err.vv b/vlib/v/checker/tests/array_contains_args_err.vv new file mode 100644 index 0000000000..b7261b16bc --- /dev/null +++ b/vlib/v/checker/tests/array_contains_args_err.vv @@ -0,0 +1,9 @@ +fn main() { + arr := [0] + mut ret := [0].contains([0]) + ret = [0].contains() + ret = [0, 1, 2].contains(0, 1, 2) + ret = [0].contains('a') + ret = [0].contains(arr) + println(ret) +}