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

checker: fix or-block expected type checking (#17469)

This commit is contained in:
Felipe Pena 2023-03-03 03:30:44 -03:00 committed by GitHub
parent e8dbcd96bd
commit 904f984367
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 4 deletions

View File

@ -1119,12 +1119,12 @@ fn (mut c Checker) check_or_last_stmt(stmt ast.Stmt, ret_type ast.Type, expr_ret
c.expected_or_type = ret_type.clear_flag(.option).clear_flag(.result)
last_stmt_typ := c.expr(stmt.expr)
if stmt.expr is ast.Ident {
if ret_type.has_flag(.option) && last_stmt_typ.has_flag(.option) {
expected_type_name := c.table.type_to_str(expr_return_type)
if ret_type.has_flag(.option) && last_stmt_typ.has_flag(.option) {
if stmt.expr in [ast.Ident, ast.SelectorExpr, ast.CallExpr] {
expected_type_name := c.table.type_to_str(ret_type.clear_flag(.option).clear_flag(.result))
got_type_name := c.table.type_to_str(last_stmt_typ)
c.error('`or` block must provide a value of type `${expected_type_name}`, not `${got_type_name}`',
stmt.expr.pos)
stmt.expr.pos())
return
}
}

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/option_return_call_non_opt_err.vv:11:22: error: `or` block must provide a value of type `int`, not `?int`
9 |
10 | fn (f Foo) get(param ?int) ?int {
11 | return param or { f.get(1) }
| ~~~~~~
12 | }
13 |

View File

@ -0,0 +1,17 @@
interface IFoo {
age ?int
get(param ?int) ?int
}
struct Foo {
age ?int
}
fn (f Foo) get(param ?int) ?int {
return param or { f.get(1) }
}
foo := IFoo(Foo{
age: 100
})
println(foo.get(100))

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/option_return_selector_non_opt_err.vv:11:22: error: `or` block must provide a value of type `int`, not `?int`
9 |
10 | fn (f Foo) get(param ?int) ?int {
11 | return param or { f.age }
| ~~~
12 | }
13 |

View File

@ -0,0 +1,17 @@
interface IFoo {
age ?int
get(param ?int) ?int
}
struct Foo {
age ?int
}
fn (f Foo) get(param ?int) ?int {
return param or { f.age }
}
foo := IFoo(Foo{
age: 100
})
println(foo.get(100))