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

checker: fix return error with multi_return optional (#16250)

This commit is contained in:
yuyi 2022-10-29 11:34:45 +08:00 committed by GitHub
parent 78c4b9a7bb
commit ee782e9119
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 6 deletions

View File

@ -94,6 +94,21 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
return
}
if expected_types.len > 0 && expected_types.len != got_types.len {
// `fn foo() !(int, string) { return Err{} }`
if (exp_is_optional || exp_is_result) && node.exprs.len == 1 {
got_typ := c.expr(node.exprs[0])
got_typ_sym := c.table.sym(got_typ)
if got_typ_sym.kind == .struct_ && c.type_implements(got_typ, ast.error_type, node.pos) {
node.exprs[0] = ast.CastExpr{
expr: node.exprs[0]
typname: 'IError'
typ: ast.error_type
expr_type: got_typ
}
node.types[0] = ast.error_type
return
}
}
arg := if expected_types.len == 1 { 'argument' } else { 'arguments' }
midx := imax(0, imin(expected_types.len, expr_idxs.len - 1))
mismatch_pos := node.exprs[expr_idxs[midx]].pos()
@ -138,6 +153,7 @@ pub fn (mut c Checker) return_stmt(mut node ast.Return) {
}
continue
}
// `fn foo() !int { return Err{} }`
if got_typ_sym.kind == .struct_
&& c.type_implements(got_typ, ast.error_type, node.pos) {
node.exprs[expr_idxs[i]] = ast.CastExpr{

View File

@ -16,9 +16,9 @@ fn foo() ?string {
}
fn bar() !(string, int) {
a := foo() or { return IError(Err{
a := foo() or { return Err{
msg: 'error test'
}) }
} }
return a, 1
}

View File

@ -12,7 +12,7 @@ fn (err MyError) code() int {
}
fn foo() int|none|IError {
return IError(MyError{})
return MyError{}
}
fn test_string_optional_none() {

View File

@ -24,7 +24,7 @@ fn parse_attrs(name string, attrs []string) !([]http.Method, string) {
}
if attr.starts_with('/') {
if path != '' {
return IError(http.MultiplePathAttributesError{})
return http.MultiplePathAttributesError{}
}
path = attr
x.delete(i)
@ -33,9 +33,9 @@ fn parse_attrs(name string, attrs []string) !([]http.Method, string) {
i++
}
if x.len > 0 {
return IError(http.UnexpectedExtraAttributeError{
return http.UnexpectedExtraAttributeError{
attributes: x
})
}
}
if methods.len == 0 {
methods = [http.Method.get]