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:
@ -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]
|
} else if node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector]
|
||||||
&& (left_type.has_flag(.option) || right_type.has_flag(.option)) {
|
&& (left_type.has_flag(.option) || right_type.has_flag(.option)) {
|
||||||
opt_comp_pos := if left_type.has_flag(.option) { left_pos } else { right_pos }
|
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)
|
opt_comp_pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -471,6 +471,11 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
|||||||
if !node.is_stmt {
|
if !node.is_stmt {
|
||||||
c.error('array append cannot be used in an expression', node.pos)
|
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`
|
// `array << elm`
|
||||||
c.check_expr_opt_call(node.right, right_type)
|
c.check_expr_opt_call(node.right, right_type)
|
||||||
node.auto_locked, _ = c.fail_if_immutable(node.left)
|
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 }
|
opt_infix_pos := if left_is_option { left_pos } else { right_pos }
|
||||||
if (node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector]
|
if (node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector]
|
||||||
|| node.op in [.eq, .ne, .lt, .gt, .le, .ge]) && right_sym.kind != .none_ {
|
|| 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)
|
right_is_result := right_type.has_flag(.result)
|
||||||
if left_is_result || right_is_result {
|
if left_is_result || right_is_result {
|
||||||
opt_infix_pos := if left_is_result { left_pos } else { right_pos }
|
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)
|
// Dual sides check (compatibility check)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
vlib/v/checker/tests/infix_compare_option_err.vv:6:5: error: unwrapped option cannot be compared in an infix expression
|
vlib/v/checker/tests/infix_compare_option_err.vv:6:5: error: unwrapped Option cannot be compared in an infix expression
|
||||||
4 |
|
4 |
|
||||||
5 | fn main() {
|
5 | fn main() {
|
||||||
6 | if foo() > foo() {
|
6 | if foo() > foo() {
|
||||||
|
@ -26,7 +26,7 @@ vlib/v/checker/tests/infix_err.vv:11:7: error: `+` cannot be used with `?int`
|
|||||||
| ^
|
| ^
|
||||||
12 | _ = int(0) + g() // FIXME not detected
|
12 | _ = int(0) + g() // FIXME not detected
|
||||||
13 | _ = g() + int(3)
|
13 | _ = g() + int(3)
|
||||||
vlib/v/checker/tests/infix_err.vv:12:14: error: unwrapped option cannot be used in an infix expression
|
vlib/v/checker/tests/infix_err.vv:12:14: error: unwrapped Option cannot be used in an infix expression
|
||||||
10 |
|
10 |
|
||||||
11 | _ = 4 + g()
|
11 | _ = 4 + g()
|
||||||
12 | _ = int(0) + g() // FIXME not detected
|
12 | _ = int(0) + g() // FIXME not detected
|
||||||
|
@ -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() {
|
1 | fn main() {
|
||||||
2 | a := ?string("hi")
|
2 | a := ?string("hi")
|
||||||
3 | println(a == 'hi')
|
3 | println(a == 'hi')
|
||||||
| ^
|
| ^
|
||||||
4 | println('hi' == a)
|
4 | println('hi' == a)
|
||||||
5 | println(a != 'hi')
|
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")
|
2 | a := ?string("hi")
|
||||||
3 | println(a == 'hi')
|
3 | println(a == 'hi')
|
||||||
4 | println('hi' == a)
|
4 | println('hi' == a)
|
||||||
| ^
|
| ^
|
||||||
5 | println(a != 'hi')
|
5 | println(a != 'hi')
|
||||||
6 | println('hi' != a)
|
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')
|
3 | println(a == 'hi')
|
||||||
4 | println('hi' == a)
|
4 | println('hi' == a)
|
||||||
5 | println(a != 'hi')
|
5 | println(a != 'hi')
|
||||||
| ^
|
| ^
|
||||||
6 | println('hi' != a)
|
6 | println('hi' != a)
|
||||||
7 | }
|
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)
|
4 | println('hi' == a)
|
||||||
5 | println(a != 'hi')
|
5 | println(a != 'hi')
|
||||||
6 | println('hi' != a)
|
6 | println('hi' != a)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
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 | }
|
3 | }
|
||||||
4 |
|
4 |
|
||||||
5 | println(test() == '')
|
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() ! {
|
5 | fn g() ! {
|
||||||
6 | assert f('1')! == true
|
6 | assert f('1')! == true
|
||||||
7 | assert f('1') == true
|
7 | assert f('1') == true
|
||||||
| ~~~~~~
|
| ~~~~~~
|
||||||
8 | }
|
8 | }
|
||||||
9 |
|
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)
|
||||||
|
}
|
Reference in New Issue
Block a user