From 5a6d440f689eef5ff00a4550fad84915297c7c19 Mon Sep 17 00:00:00 2001 From: yuyi Date: Fri, 19 Jun 2020 16:49:43 +0800 Subject: [PATCH] checker: check `array_insert` `array_prepend` type mismatch --- vlib/v/checker/checker.v | 18 ++++++++++++++++++ .../tests/array_insert_type_mismatch_a.out | 7 +++++++ .../tests/array_insert_type_mismatch_a.vv | 5 +++++ .../tests/array_insert_type_mismatch_b.out | 7 +++++++ .../tests/array_insert_type_mismatch_b.vv | 5 +++++ .../tests/array_insert_type_mismatch_c.out | 7 +++++++ .../tests/array_insert_type_mismatch_c.vv | 5 +++++ .../tests/array_insert_type_mismatch_d.out | 7 +++++++ .../tests/array_insert_type_mismatch_d.vv | 5 +++++ .../tests/array_prepend_type_mismatch_a.out | 7 +++++++ .../tests/array_prepend_type_mismatch_a.vv | 5 +++++ .../tests/array_prepend_type_mismatch_b.out | 7 +++++++ .../tests/array_prepend_type_mismatch_b.vv | 5 +++++ .../tests/array_prepend_type_mismatch_c.out | 7 +++++++ .../tests/array_prepend_type_mismatch_c.vv | 5 +++++ .../tests/array_prepend_type_mismatch_d.out | 7 +++++++ .../tests/array_prepend_type_mismatch_d.vv | 5 +++++ 17 files changed, 114 insertions(+) create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_a.out create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_a.vv create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_b.out create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_b.vv create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_c.out create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_c.vv create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_d.out create mode 100644 vlib/v/checker/tests/array_insert_type_mismatch_d.vv create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_a.out create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_a.vv create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_b.out create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_b.vv create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_c.out create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_c.vv create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_d.out create mode 100644 vlib/v/checker/tests/array_prepend_type_mismatch_d.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 683fea09a0..763048031f 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -767,6 +767,24 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { call_expr.return_type = info.elem_type call_expr.receiver_type = left_type return call_expr.return_type + } else if left_type_sym.kind == .array && method_name in ['insert', 'prepend'] { + array_info := left_type_sym.info as table.Array + elem_sym := c.table.get_type_symbol(array_info.elem_type) + arg_expr := if method_name == 'insert' { call_expr.args[1].expr } else { call_expr.args[0].expr } + arg_sym := c.table.get_type_symbol(c.expr(arg_expr)) + if arg_sym.kind == .array { + info := arg_sym.info as table.Array + sym := c.table.get_type_symbol(info.elem_type) + if sym.kind != elem_sym.kind && ((elem_sym.kind == .int && sym.kind != .any_int) || + (elem_sym.kind == .f64 && sym.kind != .any_float)) { + c.error('type mismatch, should use `$elem_sym.name[]`', arg_expr.position()) + } + } else { + if arg_sym.kind != elem_sym.kind && ((elem_sym.kind == .int && arg_sym.kind != .any_int) || + (elem_sym.kind == .f64 && arg_sym.kind != .any_float)) { + c.error('type mismatch, should use `$elem_sym.name`', arg_expr.position()) + } + } } if method := c.table.type_find_method(left_type_sym, method_name) { if !method.is_pub && !c.is_builtin_mod && !c.pref.is_test && left_type_sym.mod != c.mod && diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_a.out b/vlib/v/checker/tests/array_insert_type_mismatch_a.out new file mode 100644 index 0000000000..f18aea45a2 --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_a.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_insert_type_mismatch_a.v:3:14: error: type mismatch, should use `int` + 1 | fn main() { + 2 | mut a := [1, 2] + 3 | a.insert(1, 2.3) + | ~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_a.vv b/vlib/v/checker/tests/array_insert_type_mismatch_a.vv new file mode 100644 index 0000000000..77744c0e07 --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_a.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1, 2] + a.insert(1, 2.3) + println(a) +} diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_b.out b/vlib/v/checker/tests/array_insert_type_mismatch_b.out new file mode 100644 index 0000000000..e11fac6890 --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_b.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_insert_type_mismatch_b.v:3:14: error: type mismatch, should use `int` + 1 | fn main() { + 2 | mut a := [1, 2] + 3 | a.insert(1, 'abc') + | ~~~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_b.vv b/vlib/v/checker/tests/array_insert_type_mismatch_b.vv new file mode 100644 index 0000000000..b4c98b0361 --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_b.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1, 2] + a.insert(1, 'abc') + println(a) +} diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_c.out b/vlib/v/checker/tests/array_insert_type_mismatch_c.out new file mode 100644 index 0000000000..03d8351fef --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_c.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_insert_type_mismatch_c.v:3:14: error: type mismatch, should use `f64[]` + 1 | fn main() { + 2 | mut a := [1.1, 2.2] + 3 | a.insert(1, [2, 3]) + | ~~~~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_c.vv b/vlib/v/checker/tests/array_insert_type_mismatch_c.vv new file mode 100644 index 0000000000..a97cc2335e --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_c.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1.1, 2.2] + a.insert(1, [2, 3]) + println(a) +} diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_d.out b/vlib/v/checker/tests/array_insert_type_mismatch_d.out new file mode 100644 index 0000000000..8fc07ec565 --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_d.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_insert_type_mismatch_d.v:3:14: error: type mismatch, should use `int[]` + 1 | fn main() { + 2 | mut a := [1, 2] + 3 | a.insert(1, ['aa', 'bb', 'cc']) + | ~~~~~~~~~~~~~~~~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_insert_type_mismatch_d.vv b/vlib/v/checker/tests/array_insert_type_mismatch_d.vv new file mode 100644 index 0000000000..d5de569ffd --- /dev/null +++ b/vlib/v/checker/tests/array_insert_type_mismatch_d.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1, 2] + a.insert(1, ['aa', 'bb', 'cc']) + println(a) +} diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_a.out b/vlib/v/checker/tests/array_prepend_type_mismatch_a.out new file mode 100644 index 0000000000..b088bfa2bf --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_a.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_prepend_type_mismatch_a.v:3:12: error: type mismatch, should use `int` + 1 | fn main() { + 2 | mut a := [1, 2] + 3 | a.prepend(2.3) + | ~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_a.vv b/vlib/v/checker/tests/array_prepend_type_mismatch_a.vv new file mode 100644 index 0000000000..ca76b9672d --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_a.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1, 2] + a.prepend(2.3) + println(a) +} diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_b.out b/vlib/v/checker/tests/array_prepend_type_mismatch_b.out new file mode 100644 index 0000000000..24d12ce3ff --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_b.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_prepend_type_mismatch_b.v:3:12: error: type mismatch, should use `int` + 1 | fn main() { + 2 | mut a := [1, 2] + 3 | a.prepend('abc') + | ~~~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_b.vv b/vlib/v/checker/tests/array_prepend_type_mismatch_b.vv new file mode 100644 index 0000000000..08b8a166f0 --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_b.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1, 2] + a.prepend('abc') + println(a) +} diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_c.out b/vlib/v/checker/tests/array_prepend_type_mismatch_c.out new file mode 100644 index 0000000000..1a968ff488 --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_c.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_prepend_type_mismatch_c.v:3:12: error: type mismatch, should use `f64[]` + 1 | fn main() { + 2 | mut a := [1.1, 2.2] + 3 | a.prepend([2, 3]) + | ~~~~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_c.vv b/vlib/v/checker/tests/array_prepend_type_mismatch_c.vv new file mode 100644 index 0000000000..5d8356bdab --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_c.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1.1, 2.2] + a.prepend([2, 3]) + println(a) +} diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_d.out b/vlib/v/checker/tests/array_prepend_type_mismatch_d.out new file mode 100644 index 0000000000..1408d4d5b8 --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_d.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/array_prepend_type_mismatch_d.v:3:12: error: type mismatch, should use `int[]` + 1 | fn main() { + 2 | mut a := [1, 2] + 3 | a.prepend(['aa', 'bb', 'cc']) + | ~~~~~~~~~~~~~~~~~~ + 4 | println(a) + 5 | } diff --git a/vlib/v/checker/tests/array_prepend_type_mismatch_d.vv b/vlib/v/checker/tests/array_prepend_type_mismatch_d.vv new file mode 100644 index 0000000000..abaddfd633 --- /dev/null +++ b/vlib/v/checker/tests/array_prepend_type_mismatch_d.vv @@ -0,0 +1,5 @@ +fn main() { + mut a := [1, 2] + a.prepend(['aa', 'bb', 'cc']) + println(a) +}