From 328abb5ba8cb9f1e56dc1befdbbb15bf0e7196ac Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Sat, 6 Jan 2024 21:53:24 +0530 Subject: [PATCH] checker: enhance `for` range loop check and add better positioning (#20386) --- vlib/v/checker/for.v | 12 +++--------- vlib/v/checker/tests/for_in_range_string_type.out | 4 ++-- .../tests/invalid_mismatch_for_range_type_err.out | 4 ++++ .../tests/invalid_mismatch_for_range_type_err.vv | 2 ++ .../tests/invalid_multi_return_operations_err.out | 2 +- vlib/v/checker/tests/invalid_none_operations_err.out | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 vlib/v/checker/tests/invalid_mismatch_for_range_type_err.out create mode 100644 vlib/v/checker/tests/invalid_mismatch_for_range_type_err.vv diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index cf679945e..f087fa2e7 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -51,18 +51,12 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { if typ_idx in ast.integer_type_idxs && high_type_idx !in ast.integer_type_idxs && high_type_idx != ast.void_type_idx { c.error('range types do not match', node.cond.pos()) - } else if typ_idx in ast.float_type_idxs || high_type_idx in ast.float_type_idxs { - c.error('range type can not be float', node.cond.pos()) - } else if typ_idx == ast.bool_type_idx || high_type_idx == ast.bool_type_idx { - c.error('range type can not be bool', node.cond.pos()) - } else if typ_idx == ast.string_type_idx || high_type_idx == ast.string_type_idx { - c.error('range type can not be string', node.cond.pos()) - } else if typ_idx == ast.none_type_idx || high_type_idx == ast.none_type_idx { - c.error('range type can not be none', node.cond.pos()) } else if c.table.final_sym(typ).kind == .multi_return && c.table.final_sym(high_type).kind == .multi_return { c.error('multi-returns cannot be used in ranges. A range is from a single value to a single higher value.', - node.cond.pos()) + node.cond.pos().extend(node.high.pos())) + } else if typ_idx !in ast.integer_type_idxs { + c.error('range type can only be an integer type', node.cond.pos().extend(node.high.pos())) } if high_type in [ast.int_type, ast.int_literal_type] { node.val_type = typ diff --git a/vlib/v/checker/tests/for_in_range_string_type.out b/vlib/v/checker/tests/for_in_range_string_type.out index 4d3d53111..e9f7306ba 100644 --- a/vlib/v/checker/tests/for_in_range_string_type.out +++ b/vlib/v/checker/tests/for_in_range_string_type.out @@ -1,6 +1,6 @@ -vlib/v/checker/tests/for_in_range_string_type.vv:2:11: error: range type can not be string +vlib/v/checker/tests/for_in_range_string_type.vv:2:11: error: range type can only be an integer type 1 | fn main() { 2 | for i in 'a'..'b' { - | ~~~ + | ~~~~~~~~ 3 | println(i) 4 | } diff --git a/vlib/v/checker/tests/invalid_mismatch_for_range_type_err.out b/vlib/v/checker/tests/invalid_mismatch_for_range_type_err.out new file mode 100644 index 000000000..cb841d808 --- /dev/null +++ b/vlib/v/checker/tests/invalid_mismatch_for_range_type_err.out @@ -0,0 +1,4 @@ +vlib/v/checker/tests/invalid_mismatch_for_range_type_err.vv:1:10: error: range type can only be an integer type + 1 | for _ in map[string]string{} .. `9` { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2 | } diff --git a/vlib/v/checker/tests/invalid_mismatch_for_range_type_err.vv b/vlib/v/checker/tests/invalid_mismatch_for_range_type_err.vv new file mode 100644 index 000000000..8d4fd2e02 --- /dev/null +++ b/vlib/v/checker/tests/invalid_mismatch_for_range_type_err.vv @@ -0,0 +1,2 @@ +for _ in map[string]string{} .. `9` { +} diff --git a/vlib/v/checker/tests/invalid_multi_return_operations_err.out b/vlib/v/checker/tests/invalid_multi_return_operations_err.out index 7017ed970..1c0a06fc3 100644 --- a/vlib/v/checker/tests/invalid_multi_return_operations_err.out +++ b/vlib/v/checker/tests/invalid_multi_return_operations_err.out @@ -219,5 +219,5 @@ vlib/v/checker/tests/invalid_multi_return_operations_err.vv:25:10: error: multi- 23 | println(foo() <- foo()) 24 | 25 | for _ in foo() .. foo() { - | ~~~~~ + | ~~~~~~~~~~~~~~ 26 | } diff --git a/vlib/v/checker/tests/invalid_none_operations_err.out b/vlib/v/checker/tests/invalid_none_operations_err.out index 0279f9338..4f12feba4 100644 --- a/vlib/v/checker/tests/invalid_none_operations_err.out +++ b/vlib/v/checker/tests/invalid_none_operations_err.out @@ -240,9 +240,9 @@ vlib/v/checker/tests/invalid_none_operations_err.vv:21:1: error: `println` can n | ~~~~~~~~~~~~~~~~~~~~~ 22 | 23 | for _ in none .. none { -vlib/v/checker/tests/invalid_none_operations_err.vv:23:10: error: range type can not be none +vlib/v/checker/tests/invalid_none_operations_err.vv:23:10: error: range type can only be an integer type 21 | println(none <- none) 22 | 23 | for _ in none .. none { - | ~~~~ + | ~~~~~~~~~~~~ 24 | } -- 2.39.5