From 441637eeb4b89cb242263584f7dbce7d2a4f67fa Mon Sep 17 00:00:00 2001 From: "j. redhead" Date: Fri, 13 May 2022 16:54:49 -0500 Subject: [PATCH] checker: fix optionals in infix expression check (fix #14354) (#14390) --- vlib/v/checker/checker.v | 12 ++++++++---- vlib/v/checker/tests/infix_compare_optional_err.out | 4 ++-- vlib/v/checker/tests/infix_err.out | 4 ++-- vlib/v/checker/tests/unwrapped_optional_infix.out | 3 +-- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index af5c831591..174e2fe931 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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', - left_right_pos) + opt_comp_pos) } } .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 ` left_is_optional := left_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) { - c.error('unwrapped optional cannot be used in an infix expression', left_right_pos) + if left_is_optional && right_is_optional { + 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) if !(c.symmetric_check(left_type, right_type) && c.symmetric_check(right_type, left_type)) diff --git a/vlib/v/checker/tests/infix_compare_optional_err.out b/vlib/v/checker/tests/infix_compare_optional_err.out index f163b59c5e..8a8d27a3d6 100644 --- a/vlib/v/checker/tests/infix_compare_optional_err.out +++ b/vlib/v/checker/tests/infix_compare_optional_err.out @@ -1,6 +1,6 @@ vlib/v/checker/tests/infix_compare_optional_err.vv:6:5: error: unwrapped optional cannot be compared in an infix expression - 4 | + 4 | 5 | fn main(){ 6 | if foo() > foo() {} - | ~~~~~~~~~~~~~ + | ~~~~~ 7 | } diff --git a/vlib/v/checker/tests/infix_err.out b/vlib/v/checker/tests/infix_err.out index 363716913b..ff9049ebde 100644 --- a/vlib/v/checker/tests/infix_err.out +++ b/vlib/v/checker/tests/infix_err.out @@ -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 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 | 11 | _ = 4 + g() 12 | _ = int(0) + g() // FIXME not detected - | ~~~~~~~~~~~~ + | ~~~ 13 | _ = g() + int(3) 14 | _ = g() + 3 vlib/v/checker/tests/infix_err.vv:13:9: error: `+` cannot be used with `?int` diff --git a/vlib/v/checker/tests/unwrapped_optional_infix.out b/vlib/v/checker/tests/unwrapped_optional_infix.out index 146e7e68cc..96ab9cf705 100644 --- a/vlib/v/checker/tests/unwrapped_optional_infix.out +++ b/vlib/v/checker/tests/unwrapped_optional_infix.out @@ -2,5 +2,4 @@ vlib/v/checker/tests/unwrapped_optional_infix.vv:5:9: error: unwrapped optional 3 | } 4 | 5 | println(test() == "") - | ~~~~~~~~~~~~ - + | ~~~~~~