checker: check non-optional fn return or_block (#9227)

pull/9231/head
yuyi 2021-03-10 19:53:23 +08:00 committed by GitHub
parent 0d2bb714bc
commit a187a4abb3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 0 deletions

View File

@ -3693,6 +3693,15 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
}
ast.CallExpr {
mut ret_type := c.call_expr(mut node)
if !ret_type.has_flag(.optional) {
if node.or_block.kind == .block {
c.error('unexpected `or` block, the function `$node.name` does not return an optional',
node.or_block.pos)
} else if node.or_block.kind == .propagate {
c.error('unexpected `?`, the function `$node.name` does not return an optional',
node.or_block.pos)
}
}
if ret_type.has_flag(.optional) && node.or_block.kind != .absent {
ret_type = ret_type.clear_flag(.optional)
}

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/fn_return_or_err.vv:6:17: error: unexpected `or` block, the function `pop` does not return an optional
4 |
5 | pub fn next(mut v []Typ) Typ {
6 | return v.pop() or { Typ{} }
| ~~~~~~~~~~~~
7 | }
8 |

View File

@ -0,0 +1,13 @@
module main
pub struct Typ {}
pub fn next(mut v []Typ) Typ {
return v.pop() or { Typ{} }
}
fn main() {
mut v := [Typ{}]
last := next(mut v)
println('$last')
}