1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: disallow all operations beside assignment, on multi return values (#16890)

This commit is contained in:
Swastik Baranwal 2023-01-07 15:23:20 +05:30 committed by GitHub
parent 7fa7fec304
commit 2aced13942
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 173 additions and 0 deletions

View File

@ -62,6 +62,10 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
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())
}
if high_type in [ast.int_type, ast.int_literal_type] {
node.val_type = typ

View File

@ -65,6 +65,10 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
if left_sym.kind == .none_ && right_sym.kind == .none_ {
c.invalid_operator_error(node.op, left_type, right_type, left_right_pos)
}
if left_sym.kind == .multi_return && right_sym.kind == .multi_return {
c.error('invalid number of operand for `${node.op}`. Only one allowed on each side.',
left_right_pos)
}
if left_type.is_any_kind_of_pointer()
&& node.op in [.plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe] {
if !c.pref.translated && ((right_type.is_any_kind_of_pointer() && node.op != .minus)

View File

@ -0,0 +1,139 @@
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:5:9: error: invalid number of operand for `+`. Only one allowed on each side.
3 | }
4 |
5 | println(foo() + foo())
| ~~~~~~~~~~~~~
6 | println(foo() - foo())
7 | println(foo() * foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:6:9: error: invalid number of operand for `-`. Only one allowed on each side.
4 |
5 | println(foo() + foo())
6 | println(foo() - foo())
| ~~~~~~~~~~~~~
7 | println(foo() * foo())
8 | println(foo() / foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:7:9: error: invalid number of operand for `*`. Only one allowed on each side.
5 | println(foo() + foo())
6 | println(foo() - foo())
7 | println(foo() * foo())
| ~~~~~~~~~~~~~
8 | println(foo() / foo())
9 | println(foo() % foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:8:9: error: invalid number of operand for `/`. Only one allowed on each side.
6 | println(foo() - foo())
7 | println(foo() * foo())
8 | println(foo() / foo())
| ~~~~~~~~~~~~~
9 | println(foo() % foo())
10 | println(foo() ^ foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:9:9: error: invalid number of operand for `%`. Only one allowed on each side.
7 | println(foo() * foo())
8 | println(foo() / foo())
9 | println(foo() % foo())
| ~~~~~~~~~~~~~
10 | println(foo() ^ foo())
11 | println(foo() << foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:10:9: error: invalid number of operand for `^`. Only one allowed on each side.
8 | println(foo() / foo())
9 | println(foo() % foo())
10 | println(foo() ^ foo())
| ~~~~~~~~~~~~~
11 | println(foo() << foo())
12 | println(foo() >> foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:11:9: error: invalid number of operand for `<<`. Only one allowed on each side.
9 | println(foo() % foo())
10 | println(foo() ^ foo())
11 | println(foo() << foo())
| ~~~~~~~~~~~~~~
12 | println(foo() >> foo())
13 | println(foo() == foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:12:9: error: invalid number of operand for `>>`. Only one allowed on each side.
10 | println(foo() ^ foo())
11 | println(foo() << foo())
12 | println(foo() >> foo())
| ~~~~~~~~~~~~~~
13 | println(foo() == foo())
14 | println(foo() != foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:13:9: error: invalid number of operand for `==`. Only one allowed on each side.
11 | println(foo() << foo())
12 | println(foo() >> foo())
13 | println(foo() == foo())
| ~~~~~~~~~~~~~~
14 | println(foo() != foo())
15 | println(foo() > foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:14:9: error: invalid number of operand for `!=`. Only one allowed on each side.
12 | println(foo() >> foo())
13 | println(foo() == foo())
14 | println(foo() != foo())
| ~~~~~~~~~~~~~~
15 | println(foo() > foo())
16 | println(foo() < foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:15:9: error: invalid number of operand for `>`. Only one allowed on each side.
13 | println(foo() == foo())
14 | println(foo() != foo())
15 | println(foo() > foo())
| ~~~~~~~~~~~~~
16 | println(foo() < foo())
17 | println(foo() >= foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:16:9: error: invalid number of operand for `<`. Only one allowed on each side.
14 | println(foo() != foo())
15 | println(foo() > foo())
16 | println(foo() < foo())
| ~~~~~~~~~~~~~
17 | println(foo() >= foo())
18 | println(foo() <= foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:17:9: error: invalid number of operand for `>=`. Only one allowed on each side.
15 | println(foo() > foo())
16 | println(foo() < foo())
17 | println(foo() >= foo())
| ~~~~~~~~~~~~~~
18 | println(foo() <= foo())
19 | println(foo() && foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:18:9: error: invalid number of operand for `<=`. Only one allowed on each side.
16 | println(foo() < foo())
17 | println(foo() >= foo())
18 | println(foo() <= foo())
| ~~~~~~~~~~~~~~
19 | println(foo() && foo())
20 | println(foo() || foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:19:9: error: invalid number of operand for `&&`. Only one allowed on each side.
17 | println(foo() >= foo())
18 | println(foo() <= foo())
19 | println(foo() && foo())
| ~~~~~~~~~~~~~~
20 | println(foo() || foo())
21 | println(foo() in foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:20:9: error: invalid number of operand for `||`. Only one allowed on each side.
18 | println(foo() <= foo())
19 | println(foo() && foo())
20 | println(foo() || foo())
| ~~~~~~~~~~~~~~
21 | println(foo() in foo())
22 | println(foo() !in foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:21:9: error: invalid number of operand for `in`. Only one allowed on each side.
19 | println(foo() && foo())
20 | println(foo() || foo())
21 | println(foo() in foo())
| ~~~~~~~~~~~~~~
22 | println(foo() !in foo())
23 | println(foo() <- foo())
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:22:9: error: invalid number of operand for `!in`. Only one allowed on each side.
20 | println(foo() || foo())
21 | println(foo() in foo())
22 | println(foo() !in foo())
| ~~~~~~~~~~~~~~~
23 | println(foo() <- foo())
24 |
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:23:9: error: invalid number of operand for `<-`. Only one allowed on each side.
21 | println(foo() in foo())
22 | println(foo() !in foo())
23 | println(foo() <- foo())
| ~~~~~~~~~~~~~~
24 |
25 | for _ in foo() .. foo() {
vlib/v/checker/tests/invalid_multi_return_operations_err.vv:25:10: error: multi-returns cannot be used in ranges. A range is from a single value to a single higher value.
23 | println(foo() <- foo())
24 |
25 | for _ in foo() .. foo() {
| ~~~~~
26 | }

View File

@ -0,0 +1,26 @@
fn foo() (int, int) {
return 1, 2
}
println(foo() + foo())
println(foo() - foo())
println(foo() * foo())
println(foo() / foo())
println(foo() % foo())
println(foo() ^ foo())
println(foo() << foo())
println(foo() >> foo())
println(foo() == foo())
println(foo() != foo())
println(foo() > foo())
println(foo() < foo())
println(foo() >= foo())
println(foo() <= foo())
println(foo() && foo())
println(foo() || foo())
println(foo() in foo())
println(foo() !in foo())
println(foo() <- foo())
for _ in foo() .. foo() {
}