mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
95880dfe5c
commit
38afd74d26
@ -1156,7 +1156,7 @@ pub fn (mut t Table) find_or_register_multi_return(mr_typs []Type) int {
|
||||
mut name := '('
|
||||
mut cname := 'multi_return'
|
||||
for i, mr_typ in mr_typs {
|
||||
mr_type_sym := t.sym(mr_typ)
|
||||
mr_type_sym := t.sym(mktyp(mr_typ))
|
||||
ref, cref := if mr_typ.is_ptr() { '&', 'ref_' } else { '', '' }
|
||||
name += '$ref$mr_type_sym.name'
|
||||
cname += '_$cref$mr_type_sym.cname'
|
||||
|
@ -248,6 +248,20 @@ pub fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool {
|
||||
return true
|
||||
}
|
||||
got_sym, exp_sym := c.table.sym(got), c.table.sym(expected)
|
||||
// multi return
|
||||
if exp_sym.kind == .multi_return && got_sym.kind == .multi_return {
|
||||
exp_types := exp_sym.mr_info().types
|
||||
got_types := got_sym.mr_info().types.map(ast.mktyp(it))
|
||||
if exp_types.len != got_types.len {
|
||||
return false
|
||||
}
|
||||
for i in 0 .. exp_types.len {
|
||||
if !c.check_types(got_types[i], exp_types[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
// array/map as argument
|
||||
if got_sym.kind in [.array, .map, .array_fixed] && exp_sym.kind == got_sym.kind {
|
||||
if c.table.type_to_str(got) == c.table.type_to_str(expected).trim('&') {
|
||||
|
@ -217,16 +217,6 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
|
||||
if is_noreturn_callexpr(last_expr.expr) {
|
||||
continue
|
||||
}
|
||||
node_sym := c.table.sym(node.typ)
|
||||
last_sym := c.table.sym(last_expr.typ)
|
||||
if node_sym.kind == .multi_return && last_sym.kind == .multi_return {
|
||||
node_types := node_sym.mr_info().types
|
||||
last_types := last_sym.mr_info().types.map(ast.mktyp(it))
|
||||
if node_types == last_types {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(last_expr.typ)}`',
|
||||
node.pos)
|
||||
}
|
||||
|
@ -195,6 +195,7 @@ mut:
|
||||
referenced_fns shared map[string]bool // functions that have been referenced
|
||||
nr_closures int
|
||||
expected_cast_type ast.Type // for match expr of sumtypes
|
||||
or_expr_return_type ast.Type // or { 0, 1 } return type
|
||||
anon_fn bool
|
||||
tests_inited bool
|
||||
has_main bool
|
||||
@ -3864,6 +3865,8 @@ fn (mut g Gen) concat_expr(node ast.ConcatExpr) {
|
||||
mut styp := g.typ(node.return_type)
|
||||
if g.inside_return {
|
||||
styp = g.typ(g.fn_decl.return_type)
|
||||
} else if g.inside_or_block {
|
||||
styp = g.typ(g.or_expr_return_type)
|
||||
}
|
||||
sym := g.table.sym(node.return_type)
|
||||
is_multi := sym.kind == .multi_return
|
||||
@ -4933,6 +4936,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
|
||||
g.writeln('if (${cvar_name}.state != 0) { /*or block*/ ')
|
||||
}
|
||||
if or_block.kind == .block {
|
||||
g.or_expr_return_type = return_type.clear_flag(.optional)
|
||||
if g.inside_or_block {
|
||||
g.writeln('\terr = ${cvar_name}.err;')
|
||||
} else {
|
||||
@ -4970,6 +4974,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type ast.Ty
|
||||
g.writeln(';')
|
||||
}
|
||||
}
|
||||
g.or_expr_return_type = ast.void_type
|
||||
} else if or_block.kind == .propagate {
|
||||
if g.file.mod.name == 'main' && (isnil(g.fn_decl) || g.fn_decl.is_main) {
|
||||
// In main(), an `opt()?` call is sugar for `opt() or { panic(err) }`
|
||||
|
31
vlib/v/tests/multiret_in_or_expr_test.v
Normal file
31
vlib/v/tests/multiret_in_or_expr_test.v
Normal file
@ -0,0 +1,31 @@
|
||||
fn multi_return1() ?(int, int) {
|
||||
return 1, 2
|
||||
}
|
||||
|
||||
fn multi_return2() ?(i64, i64) {
|
||||
return 11, 22
|
||||
}
|
||||
|
||||
fn multi_return3() ?(int, i64) {
|
||||
return 11, 22
|
||||
}
|
||||
|
||||
fn test_multi_return_in_or_expr() {
|
||||
a1, b1 := multi_return1() or { 0, -1 }
|
||||
|
||||
println('$a1, $b1')
|
||||
assert a1 == 1
|
||||
assert b1 == 2
|
||||
|
||||
a2, b2 := multi_return2() or { 0, -1 }
|
||||
|
||||
println('$a2, $b2')
|
||||
assert a2 == 11
|
||||
assert b2 == 22
|
||||
|
||||
a3, b3 := multi_return3() or { 0, -1 }
|
||||
|
||||
println('$a3, $b3')
|
||||
assert a3 == 11
|
||||
assert b3 == 22
|
||||
}
|
Loading…
Reference in New Issue
Block a user