mirror of
https://github.com/vlang/v.git
synced 2025-09-13 17:36:52 -04:00
This commit is contained in:
parent
61e38b9bf1
commit
aca5358061
@ -5527,7 +5527,9 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
fn_return_is_multi := sym.kind == .multi_return
|
||||
fn_return_is_option := fn_ret_type.has_flag(.option)
|
||||
fn_return_is_result := fn_ret_type.has_flag(.result)
|
||||
fn_return_is_fixed_array := sym.is_array_fixed() && !fn_ret_type.has_option_or_result()
|
||||
fn_return_is_fixed_array := sym.is_array_fixed()
|
||||
fn_return_is_fixed_array_non_result := fn_return_is_fixed_array
|
||||
&& !fn_ret_type.has_option_or_result()
|
||||
|
||||
mut has_semicolon := false
|
||||
if node.exprs.len == 0 {
|
||||
@ -5573,7 +5575,7 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
mut use_tmp_var := g.defer_stmts.len > 0 || g.defer_profile_code.len > 0
|
||||
|| g.cur_lock.lockeds.len > 0
|
||||
|| (fn_return_is_multi && node.exprs.len >= 1 && fn_return_is_option)
|
||||
|| fn_return_is_fixed_array
|
||||
|| fn_return_is_fixed_array_non_result
|
||||
|| (fn_return_is_multi && node.types.any(g.table.final_sym(it).kind == .array_fixed))
|
||||
// handle promoting none/error/function returning _option'
|
||||
if fn_return_is_option {
|
||||
@ -5788,17 +5790,12 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
g.write('*')
|
||||
}
|
||||
}
|
||||
for i, expr in node.exprs {
|
||||
if return_sym.kind == .array_fixed && expr !is ast.ArrayInit {
|
||||
info := return_sym.info as ast.ArrayFixed
|
||||
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
|
||||
info.elem_type, info.size)
|
||||
} else {
|
||||
g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_option_and_result())
|
||||
}
|
||||
if i < node.exprs.len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
if return_sym.kind == .array_fixed && expr0 !is ast.ArrayInit {
|
||||
info := return_sym.info as ast.ArrayFixed
|
||||
g.fixed_array_var_init(g.expr_string(expr0), expr0.is_auto_deref_var(),
|
||||
info.elem_type, info.size)
|
||||
} else {
|
||||
g.expr_with_cast(expr0, node.types[0], fn_ret_type.clear_option_and_result())
|
||||
}
|
||||
g.writeln(' }, (${option_name}*)(&${tmpvar}), sizeof(${styp}));')
|
||||
g.write_defer_stmts_when_needed()
|
||||
@ -5815,29 +5812,37 @@ fn (mut g Gen) return_stmt(node ast.Return) {
|
||||
}
|
||||
}
|
||||
if fn_return_is_result && !expr_type_is_result && return_sym.name != result_name {
|
||||
styp := g.base_type(fn_ret_type)
|
||||
g.writeln('${ret_typ} ${tmpvar};')
|
||||
g.write('_result_ok(&(${styp}[]) { ')
|
||||
if !fn_ret_type.is_ptr() && node.types[0].is_ptr() {
|
||||
if !((node.exprs[0] is ast.Ident && !g.is_amp) || sym.kind == .interface) {
|
||||
g.write('*')
|
||||
g.writeln('${ret_typ} ${tmpvar} = {0};')
|
||||
if fn_return_is_fixed_array && expr0 !is ast.ArrayInit
|
||||
&& g.table.final_sym(node.types[0]).kind == .array_fixed {
|
||||
styp := g.styp(fn_ret_type.clear_option_and_result())
|
||||
g.write('memcpy(${tmpvar}.data, ')
|
||||
if expr0 in [ast.CallExpr, ast.StructInit] {
|
||||
g.expr_with_opt(expr0, node.types[0], fn_ret_type)
|
||||
g.write('.data')
|
||||
} else {
|
||||
g.expr(expr0)
|
||||
}
|
||||
g.writeln(', sizeof(${styp}));')
|
||||
} else {
|
||||
styp := g.base_type(fn_ret_type)
|
||||
g.write('_result_ok(&(${styp}[]) { ')
|
||||
if !fn_ret_type.is_ptr() && node.types[0].is_ptr() {
|
||||
if !((node.exprs[0] is ast.Ident && !g.is_amp) || sym.kind == .interface) {
|
||||
g.write('*')
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, expr in node.exprs {
|
||||
if fn_ret_type.has_flag(.option) {
|
||||
g.expr_with_opt(expr, node.types[i], fn_ret_type.clear_flag(.result))
|
||||
} else if return_sym.kind == .array_fixed && expr !is ast.ArrayInit {
|
||||
g.expr_with_opt(expr0, node.types[0], fn_ret_type.clear_flag(.result))
|
||||
} else if return_sym.kind == .array_fixed && expr0 !is ast.ArrayInit {
|
||||
info := return_sym.info as ast.ArrayFixed
|
||||
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
|
||||
g.fixed_array_var_init(g.expr_string(expr0), expr0.is_auto_deref_var(),
|
||||
info.elem_type, info.size)
|
||||
} else {
|
||||
g.expr_with_cast(expr, node.types[i], fn_ret_type.clear_flag(.result))
|
||||
}
|
||||
if i < node.exprs.len - 1 {
|
||||
g.write(', ')
|
||||
g.expr_with_cast(expr0, node.types[0], fn_ret_type.clear_flag(.result))
|
||||
}
|
||||
g.writeln(' }, (${result_name}*)(&${tmpvar}), sizeof(${styp}));')
|
||||
}
|
||||
g.writeln(' }, (${result_name}*)(&${tmpvar}), sizeof(${styp}));')
|
||||
g.write_defer_stmts_when_needed()
|
||||
g.autofree_scope_vars(node.pos.pos - 1, node.pos.line_nr, true)
|
||||
g.writeln('return ${tmpvar};')
|
||||
@ -7180,7 +7185,7 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
|
||||
mut is_array_fixed := false
|
||||
mut return_wrapped := false
|
||||
if is_option {
|
||||
is_array_fixed = expr_stmt.expr is ast.ArrayInit
|
||||
is_array_fixed = expr_stmt.expr in [ast.ArrayInit, ast.CastExpr]
|
||||
&& g.table.final_sym(return_type).kind == .array_fixed
|
||||
if !is_array_fixed {
|
||||
if g.inside_return && !g.inside_struct_init
|
||||
|
40
vlib/v/tests/fns/fixed_array_result_return_test.v
Normal file
40
vlib/v/tests/fns/fixed_array_result_return_test.v
Normal file
@ -0,0 +1,40 @@
|
||||
module main
|
||||
|
||||
type Foo = [4]u8
|
||||
|
||||
fn Foo.new(el []u8) !Foo {
|
||||
if el.len != 4 {
|
||||
return error('el must have 4 members')
|
||||
}
|
||||
mut bytes := [4]u8{}
|
||||
for i := 0; i < 4; i++ {
|
||||
bytes[i] = el[i]
|
||||
}
|
||||
return Foo(bytes)
|
||||
}
|
||||
|
||||
fn Foo.new_no_err(el []u8) Foo {
|
||||
mut bytes := [4]u8{}
|
||||
for i := 0; i < 4; i++ {
|
||||
bytes[i] = el[i]
|
||||
}
|
||||
return Foo(bytes)
|
||||
}
|
||||
|
||||
fn (f Foo) str() string {
|
||||
return '${f[0]}, ${f[1]}, ${f[2]}, ${f[3]}'
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
a := Foo.new_no_err([u8(5), 4, 3, 2])
|
||||
println(a)
|
||||
assert a == [u8(5), 4, 3, 2]!
|
||||
|
||||
b := Foo.new([u8(1), 2, 3, 4])!
|
||||
println(b)
|
||||
assert b == [u8(1), 2, 3, 4]!
|
||||
|
||||
c := Foo.new([u8(1), 2, 3, 4]) or { Foo([u8(0), 0, 0, 0]!) }
|
||||
println(c)
|
||||
assert c == [u8(1), 2, 3, 4]!
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user