mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix missing check for unwrapped shift operation (#18451)
This commit is contained in:
parent
84cf448f2f
commit
d17f6f69cd
@ -457,7 +457,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
} else if node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector]
|
||||
&& (left_type.has_flag(.option) || right_type.has_flag(.option)) {
|
||||
opt_comp_pos := if left_type.has_flag(.option) { left_pos } else { right_pos }
|
||||
c.error('unwrapped option cannot be compared in an infix expression',
|
||||
c.error('unwrapped Option cannot be compared in an infix expression',
|
||||
opt_comp_pos)
|
||||
}
|
||||
}
|
||||
@ -471,6 +471,11 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
if !node.is_stmt {
|
||||
c.error('array append cannot be used in an expression', node.pos)
|
||||
}
|
||||
if left_type.has_flag(.option) && node.left is ast.Ident
|
||||
&& (node.left as ast.Ident).or_expr.kind == .absent {
|
||||
c.error('unwrapped Option cannot be used in an infix expression',
|
||||
node.pos)
|
||||
}
|
||||
// `array << elm`
|
||||
c.check_expr_opt_call(node.right, right_type)
|
||||
node.auto_locked, _ = c.fail_if_immutable(node.left)
|
||||
@ -695,7 +700,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
opt_infix_pos := if left_is_option { left_pos } else { right_pos }
|
||||
if (node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector]
|
||||
|| node.op in [.eq, .ne, .lt, .gt, .le, .ge]) && right_sym.kind != .none_ {
|
||||
c.error('unwrapped option cannot be used in an infix expression', opt_infix_pos)
|
||||
c.error('unwrapped Option cannot be used in an infix expression', opt_infix_pos)
|
||||
}
|
||||
}
|
||||
|
||||
@ -703,7 +708,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
right_is_result := right_type.has_flag(.result)
|
||||
if left_is_result || right_is_result {
|
||||
opt_infix_pos := if left_is_result { left_pos } else { right_pos }
|
||||
c.error('unwrapped result cannot be used in an infix expression', opt_infix_pos)
|
||||
c.error('unwrapped Result cannot be used in an infix expression', opt_infix_pos)
|
||||
}
|
||||
|
||||
// Dual sides check (compatibility check)
|
||||
|
@ -1,7 +1,7 @@
|
||||
vlib/v/checker/tests/infix_compare_option_err.vv:6:5: error: unwrapped option cannot be compared in an infix expression
|
||||
4 |
|
||||
vlib/v/checker/tests/infix_compare_option_err.vv:6:5: error: unwrapped Option cannot be compared in an infix expression
|
||||
4 |
|
||||
5 | fn main() {
|
||||
6 | if foo() > foo() {
|
||||
| ~~~~~
|
||||
7 | }
|
||||
8 | }
|
||||
8 | }
|
||||
|
@ -17,17 +17,17 @@ vlib/v/checker/tests/infix_err.vv:9:9: error: `+` cannot be used with `?string`
|
||||
8 | _ = f() + ''
|
||||
9 | _ = f() + f()
|
||||
| ^
|
||||
10 |
|
||||
10 |
|
||||
11 | _ = 4 + g()
|
||||
vlib/v/checker/tests/infix_err.vv:11:7: error: `+` cannot be used with `?int`
|
||||
9 | _ = f() + f()
|
||||
10 |
|
||||
10 |
|
||||
11 | _ = 4 + g()
|
||||
| ^
|
||||
12 | _ = int(0) + g() // FIXME not detected
|
||||
13 | _ = g() + int(3)
|
||||
vlib/v/checker/tests/infix_err.vv:12:14: error: unwrapped option cannot be used in an infix expression
|
||||
10 |
|
||||
vlib/v/checker/tests/infix_err.vv:12:14: error: unwrapped Option cannot be used in an infix expression
|
||||
10 |
|
||||
11 | _ = 4 + g()
|
||||
12 | _ = int(0) + g() // FIXME not detected
|
||||
| ~~~
|
||||
@ -45,10 +45,10 @@ vlib/v/checker/tests/infix_err.vv:14:9: error: `+` cannot be used with `?int`
|
||||
13 | _ = g() + int(3)
|
||||
14 | _ = g() + 3
|
||||
| ^
|
||||
15 |
|
||||
15 |
|
||||
16 | // binary operands
|
||||
vlib/v/checker/tests/infix_err.vv:17:5: error: left operand for `&&` is not a boolean
|
||||
15 |
|
||||
15 |
|
||||
16 | // binary operands
|
||||
17 | _ = 1 && 2
|
||||
| ^
|
||||
@ -59,10 +59,10 @@ vlib/v/checker/tests/infix_err.vv:18:13: error: right operand for `||` is not a
|
||||
17 | _ = 1 && 2
|
||||
18 | _ = true || 2
|
||||
| ^
|
||||
19 |
|
||||
19 |
|
||||
20 | // boolean expressions
|
||||
vlib/v/checker/tests/infix_err.vv:21:22: error: ambiguous boolean expression. use `()` to ensure correct order of operations
|
||||
19 |
|
||||
19 |
|
||||
20 | // boolean expressions
|
||||
21 | _ = 1 == 1 && 2 == 2 || 3 == 3
|
||||
| ~~
|
||||
@ -78,4 +78,4 @@ vlib/v/checker/tests/infix_err.vv:24:2: error: ambiguous boolean expression. use
|
||||
22 | _ = 1 == 1
|
||||
23 | && 2 == 2 || 3 == 3
|
||||
24 | && 4 == 4
|
||||
| ~~
|
||||
| ~~
|
||||
|
@ -1,25 +1,25 @@
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:3:10: error: unwrapped option cannot be used in an infix expression
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:3:10: error: unwrapped Option cannot be used in an infix expression
|
||||
1 | fn main() {
|
||||
2 | a := ?string("hi")
|
||||
3 | println(a == 'hi')
|
||||
| ^
|
||||
4 | println('hi' == a)
|
||||
5 | println(a != 'hi')
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:4:18: error: unwrapped option cannot be used in an infix expression
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:4:18: error: unwrapped Option cannot be used in an infix expression
|
||||
2 | a := ?string("hi")
|
||||
3 | println(a == 'hi')
|
||||
4 | println('hi' == a)
|
||||
| ^
|
||||
5 | println(a != 'hi')
|
||||
6 | println('hi' != a)
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:5:10: error: unwrapped option cannot be used in an infix expression
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:5:10: error: unwrapped Option cannot be used in an infix expression
|
||||
3 | println(a == 'hi')
|
||||
4 | println('hi' == a)
|
||||
5 | println(a != 'hi')
|
||||
| ^
|
||||
6 | println('hi' != a)
|
||||
7 | }
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:6:18: error: unwrapped option cannot be used in an infix expression
|
||||
vlib/v/checker/tests/option_wrapped_cmp_op_err.vv:6:18: error: unwrapped Option cannot be used in an infix expression
|
||||
4 | println('hi' == a)
|
||||
5 | println(a != 'hi')
|
||||
6 | println('hi' != a)
|
||||
|
@ -1,5 +1,5 @@
|
||||
vlib/v/checker/tests/unwrapped_option_infix.vv:5:9: error: unwrapped option cannot be used in an infix expression
|
||||
vlib/v/checker/tests/unwrapped_option_infix.vv:5:9: error: unwrapped Option cannot be used in an infix expression
|
||||
3 | }
|
||||
4 |
|
||||
4 |
|
||||
5 | println(test() == '')
|
||||
| ~~~~~~
|
||||
| ~~~~~~
|
||||
|
@ -1,8 +1,7 @@
|
||||
vlib/v/checker/tests/unwrapped_result_infix_err.vv:7:9: error: unwrapped result cannot be used in an infix expression
|
||||
vlib/v/checker/tests/unwrapped_result_infix_err.vv:7:9: error: unwrapped Result cannot be used in an infix expression
|
||||
5 | fn g() ! {
|
||||
6 | assert f('1')! == true
|
||||
7 | assert f('1') == true
|
||||
| ~~~~~~
|
||||
8 | }
|
||||
9 |
|
||||
|
||||
|
14
vlib/v/checker/tests/wrong_shift_left_option_err.out
Normal file
14
vlib/v/checker/tests/wrong_shift_left_option_err.out
Normal file
@ -0,0 +1,14 @@
|
||||
vlib/v/checker/tests/wrong_shift_left_option_err.vv:7:4: error: unwrapped Option cannot be used in an infix expression
|
||||
5 | fn main() {
|
||||
6 | mut a := ?[]SomeStruct([SomeStruct{}, SomeStruct{}]) // struct type
|
||||
7 | a << []SomeStruct{len: 20}
|
||||
| ~~
|
||||
8 | mut b := ?[]int([2, 8]) // primitive type
|
||||
9 | b << [1, 3, 4]
|
||||
vlib/v/checker/tests/wrong_shift_left_option_err.vv:9:4: error: unwrapped Option cannot be used in an infix expression
|
||||
7 | a << []SomeStruct{len: 20}
|
||||
8 | mut b := ?[]int([2, 8]) // primitive type
|
||||
9 | b << [1, 3, 4]
|
||||
| ~~
|
||||
10 | dump(a?.len)
|
||||
11 | dump(b)
|
12
vlib/v/checker/tests/wrong_shift_left_option_err.vv
Normal file
12
vlib/v/checker/tests/wrong_shift_left_option_err.vv
Normal file
@ -0,0 +1,12 @@
|
||||
pub struct SomeStruct {
|
||||
i int
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut a := ?[]SomeStruct([SomeStruct{}, SomeStruct{}]) // struct type
|
||||
a << []SomeStruct{len: 20}
|
||||
mut b := ?[]int([2, 8]) // primitive type
|
||||
b << [1, 3, 4]
|
||||
dump(a?.len)
|
||||
dump(b)
|
||||
}
|
Loading…
Reference in New Issue
Block a user