checker: fix optionals in infix expression check (fix #14354) (#14390)

master
j. redhead 2022-05-13 16:54:49 -05:00 committed by GitHub
parent cee7856c0f
commit 441637eeb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 10 deletions

View File

@ -927,9 +927,10 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
} }
} }
} }
} else if left_type.has_flag(.optional) && right_type.has_flag(.optional) { } else if left_type.has_flag(.optional) || right_type.has_flag(.optional) {
opt_comp_pos := if left_type.has_flag(.optional) { left_pos } else { right_pos }
c.error('unwrapped optional cannot be compared in an infix expression', c.error('unwrapped optional cannot be compared in an infix expression',
left_right_pos) opt_comp_pos)
} }
} }
.left_shift { .left_shift {
@ -1143,8 +1144,11 @@ pub 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 ` // TODO move this to symmetric_check? Right now it would break `return 0` for `fn()?int `
left_is_optional := left_type.has_flag(.optional) left_is_optional := left_type.has_flag(.optional)
right_is_optional := right_type.has_flag(.optional) right_is_optional := right_type.has_flag(.optional)
if (left_is_optional && !right_is_optional) || (!left_is_optional && right_is_optional) { if left_is_optional && right_is_optional {
c.error('unwrapped optional cannot be used in an infix expression', left_right_pos) c.error('unwrapped optionals cannot be used in an infix expression', left_right_pos)
} else if left_is_optional || right_is_optional {
opt_infix_pos := if left_is_optional { left_pos } else { right_pos }
c.error('unwrapped optional cannot be used in an infix expression', opt_infix_pos)
} }
// Dual sides check (compatibility check) // Dual sides check (compatibility check)
if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type)) if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type))

View File

@ -2,5 +2,5 @@ vlib/v/checker/tests/infix_compare_optional_err.vv:6:5: error: unwrapped optiona
4 | 4 |
5 | fn main(){ 5 | fn main(){
6 | if foo() > foo() {} 6 | if foo() > foo() {}
| ~~~~~~~~~~~~~ | ~~~~~
7 | } 7 | }

View File

@ -26,11 +26,11 @@ 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:5: error: unwrapped optional cannot be used in an infix expression vlib/v/checker/tests/infix_err.vv:12:14: error: unwrapped optional 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
| ~~~~~~~~~~~~ | ~~~
13 | _ = g() + int(3) 13 | _ = g() + int(3)
14 | _ = g() + 3 14 | _ = g() + 3
vlib/v/checker/tests/infix_err.vv:13:9: error: `+` cannot be used with `?int` vlib/v/checker/tests/infix_err.vv:13:9: error: `+` cannot be used with `?int`

View File

@ -2,5 +2,4 @@ vlib/v/checker/tests/unwrapped_optional_infix.vv:5:9: error: unwrapped optional
3 | } 3 | }
4 | 4 |
5 | println(test() == "") 5 | println(test() == "")
| ~~~~~~~~~~~~ | ~~~~~~