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 name := '('
|
||||||
mut cname := 'multi_return'
|
mut cname := 'multi_return'
|
||||||
for i, mr_typ in mr_typs {
|
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 { '', '' }
|
ref, cref := if mr_typ.is_ptr() { '&', 'ref_' } else { '', '' }
|
||||||
name += '$ref$mr_type_sym.name'
|
name += '$ref$mr_type_sym.name'
|
||||||
cname += '_$cref$mr_type_sym.cname'
|
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
|
return true
|
||||||
}
|
}
|
||||||
got_sym, exp_sym := c.table.sym(got), c.table.sym(expected)
|
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
|
// array/map as argument
|
||||||
if got_sym.kind in [.array, .map, .array_fixed] && exp_sym.kind == got_sym.kind {
|
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('&') {
|
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) {
|
if is_noreturn_callexpr(last_expr.expr) {
|
||||||
continue
|
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)}`',
|
c.error('mismatched types `${c.table.type_to_str(node.typ)}` and `${c.table.type_to_str(last_expr.typ)}`',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,6 +195,7 @@ mut:
|
||||||
referenced_fns shared map[string]bool // functions that have been referenced
|
referenced_fns shared map[string]bool // functions that have been referenced
|
||||||
nr_closures int
|
nr_closures int
|
||||||
expected_cast_type ast.Type // for match expr of sumtypes
|
expected_cast_type ast.Type // for match expr of sumtypes
|
||||||
|
or_expr_return_type ast.Type // or { 0, 1 } return type
|
||||||
anon_fn bool
|
anon_fn bool
|
||||||
tests_inited bool
|
tests_inited bool
|
||||||
has_main bool
|
has_main bool
|
||||||
|
@ -3864,6 +3865,8 @@ fn (mut g Gen) concat_expr(node ast.ConcatExpr) {
|
||||||
mut styp := g.typ(node.return_type)
|
mut styp := g.typ(node.return_type)
|
||||||
if g.inside_return {
|
if g.inside_return {
|
||||||
styp = g.typ(g.fn_decl.return_type)
|
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)
|
sym := g.table.sym(node.return_type)
|
||||||
is_multi := sym.kind == .multi_return
|
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*/ ')
|
g.writeln('if (${cvar_name}.state != 0) { /*or block*/ ')
|
||||||
}
|
}
|
||||||
if or_block.kind == .block {
|
if or_block.kind == .block {
|
||||||
|
g.or_expr_return_type = return_type.clear_flag(.optional)
|
||||||
if g.inside_or_block {
|
if g.inside_or_block {
|
||||||
g.writeln('\terr = ${cvar_name}.err;')
|
g.writeln('\terr = ${cvar_name}.err;')
|
||||||
} else {
|
} 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.writeln(';')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g.or_expr_return_type = ast.void_type
|
||||||
} else if or_block.kind == .propagate {
|
} else if or_block.kind == .propagate {
|
||||||
if g.file.mod.name == 'main' && (isnil(g.fn_decl) || g.fn_decl.is_main) {
|
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) }`
|
// In main(), an `opt()?` call is sugar for `opt() or { panic(err) }`
|
||||||
|
|
|
@ -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