checker: handle unwrapped optionals in infix exprs

pull/7688/head
Alexander Medvednikov 2020-12-29 13:49:43 +01:00
parent d69993a40e
commit 40ce18fa3c
4 changed files with 21 additions and 0 deletions

View File

@ -16,6 +16,11 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
exp_idx := t.unalias_num_type(expected).idx()
// got_is_ptr := got.is_ptr()
exp_is_ptr := expected.is_ptr()
// exp_is_optional := expected.has_flag(.optional)
// got_is_optional := got.has_flag(.optional)
// if (exp_is_optional && !got_is_optional) || (!exp_is_optional && got_is_optional) {
// return false
//}
// println('check: $got_type_sym.name, $exp_type_sym.name')
// # NOTE: use idxs here, and symbols below for perf
if got_idx == exp_idx {

View File

@ -910,6 +910,12 @@ pub fn (mut c Checker) infix_expr(mut infix_expr ast.InfixExpr) table.Type {
} else if c.table.type_kind(right_type) == .sum_type {
c.error('cannot use operator `$infix_expr.op` with `$right.name`', infix_expr.pos)
}
// 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', infix_expr.pos)
}
// Dual sides check (compatibility check)
if !c.symmetric_check(right_type, left_type) && !c.pref.translated {
// for type-unresolved consts

View File

@ -0,0 +1,5 @@
vlib/v/checker/tests/unwrapped_optional_infix.vv:5:16: error: unwrapped optional cannot be used in an infix expression
3 | }
4 |
5 | println(test() == "")
|

View File

@ -0,0 +1,5 @@
fn test() ?string {
return ""
}
println(test() == "")