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

checker: check wrapped Option types before comparison (#17590)

This commit is contained in:
Swastik Baranwal 2023-03-11 14:46:12 +05:30 committed by GitHub
parent b691e1e24a
commit 48a03a4874
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 4 deletions

View File

@ -669,10 +669,12 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
// TODO move this to symmetric_check? Right now it would break `return 0` for `fn()?int `
left_is_option := left_type.has_flag(.option)
right_is_option := right_type.has_flag(.option)
if node.left !in [ast.Ident, ast.SelectorExpr, ast.ComptimeSelector]
&& (left_is_option || right_is_option) {
if left_is_option || right_is_option {
opt_infix_pos := if left_is_option { left_pos } else { right_pos }
c.error('unwrapped option cannot be used in an infix expression', opt_infix_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)
}
}
left_is_result := left_type.has_flag(.result)

View File

@ -0,0 +1,27 @@
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
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
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
4 | println('hi' == a)
5 | println(a != 'hi')
6 | println('hi' != a)
| ^
7 | }

View File

@ -0,0 +1,7 @@
fn main() {
a := ?string("hi")
println(a == 'hi')
println('hi' == a)
println(a != 'hi')
println('hi' != a)
}

View File

@ -10,7 +10,7 @@ fn foo(val ?int) (?int, ?int) {
fn test_multi_return() {
a, b := foo(100)
assert a == 100
assert a? == 100
assert b == none
}