@@ -2359,10 +2359,16 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
23592359 panic ('cgen: parameter `ret_typ` of function `expr_with_tmp_var()` must be an Option or Result' )
23602360 }
23612361
2362+ assign_op := g.assign_op
2363+ defer {
2364+ g.assign_op = assign_op
2365+ }
2366+ g.assign_op = .unknown
23622367 stmt_str := g.go_before_last_stmt ().trim_space ()
23632368 mut styp := g.base_type (ret_typ)
23642369 g.empty_line = true
23652370 final_expr_sym := g.table.final_sym (expr_typ)
2371+ mut expected_type := ret_typ
23662372
23672373 if final_expr_sym.kind == .none {
23682374 g.write ('${g .styp (ret_typ )} ${tmp_var } = ' )
@@ -2435,11 +2441,6 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
24352441 && (expr.right as ast.StructInit ).init_fields.len == 0 {
24362442 g.write ('builtin___option_none(&(${styp }[]) { ' )
24372443 } else if final_expr_sym.kind == .array_fixed {
2438- assign_op := g.assign_op
2439- defer (fn ) {
2440- g.assign_op = assign_op
2441- }
2442- g.assign_op = .unknown
24432444 expr_is_fixed_array_var = true
24442445 info := final_expr_sym.array_fixed_info ()
24452446 mut no_cast := false
@@ -2486,10 +2487,29 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
24862487 }
24872488 }
24882489 } else {
2489- g.write ('builtin___result_ok(&(${styp }[]) { ' )
2490+ if final_expr_sym.kind == .array_fixed {
2491+ expr_is_fixed_array_var = true
2492+ info := final_expr_sym.array_fixed_info ()
2493+ mut no_cast := false
2494+ if expr in [ast.CastExpr, ast.CallExpr, ast.Ident, ast.SelectorExpr] {
2495+ no_cast = true
2496+ }
2497+ elem_sym := g.table.sym (info.elem_type)
2498+ if elem_sym.kind == .struct {
2499+ expr_is_fixed_array_var = false
2500+ g.write ('builtin___result_ok(&(${styp }[]) { ' )
2501+ } else if no_cast {
2502+ g.write ('builtin___result_ok(' )
2503+ } else {
2504+ g.write ('builtin___result_ok((${g .styp (final_expr_sym .idx )})' )
2505+ }
2506+ } else {
2507+ g.write ('builtin___result_ok(&(${styp }[]) { ' )
2508+ expected_type = ret_typ.clear_flag (.result)
2509+ }
24902510 }
24912511 if ! already_generated {
2492- g.expr_with_cast (expr, expr_typ, ret_typ )
2512+ g.expr_with_cast (expr, expr_typ, expected_type )
24932513 }
24942514
24952515 if fn_option_clone {
@@ -2504,7 +2524,11 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
25042524 g.writeln (' }, (${option_name }*)(&${tmp_var }), sizeof(${styp }));' )
25052525 }
25062526 } else {
2507- g.writeln (' }, (${result_name }*)(&${tmp_var }), sizeof(${styp }));' )
2527+ if expr_is_fixed_array_var {
2528+ g.writeln (', (${result_name }*)(&${tmp_var }), sizeof(${styp }));' )
2529+ } else {
2530+ g.writeln (' }, (${result_name }*)(&${tmp_var }), sizeof(${styp }));' )
2531+ }
25082532 }
25092533 g.set_current_pos_as_last_stmt_pos ()
25102534 }
@@ -6444,17 +6468,6 @@ fn (mut g Gen) return_stmt(node ast.Return) {
64446468 type0 .has_flag (.option)
64456469 }
64466470 }
6447- if fn_return_is_option && ! expr_type_is_opt && return_sym.name != option_name {
6448- g.expr_with_tmp_var (expr0 , type0 , fn_ret_type, tmpvar, false )
6449- g.writeln ('' )
6450- g.write_defer_stmts_when_needed (node.scope, true , node.pos)
6451- if g.is_autofree {
6452- g.detect_used_var_on_return (expr0 )
6453- }
6454- g.autofree_scope_vars (node.pos.pos - 1 , node.pos.line_nr, true )
6455- g.writeln ('return ${tmpvar };' )
6456- return
6457- }
64586471 expr_type_is_result := match expr0 {
64596472 ast.CallExpr {
64606473 expr0 .return_type.has_flag (.result) && expr0 .or_block.kind == .absent
@@ -6463,38 +6476,10 @@ fn (mut g Gen) return_stmt(node ast.Return) {
64636476 type0 .has_flag (.result)
64646477 }
64656478 }
6466- if fn_return_is_result && ! expr_type_is_result && return_sym.name != result_name {
6467- g.writeln ('${ret_typ } ${tmpvar } = {0};' )
6468- if fn_return_is_fixed_array && expr0 ! is ast.ArrayInit
6469- && g.table.final_sym (type0 ).kind == .array_fixed {
6470- styp := g.styp (fn_ret_type.clear_option_and_result ())
6471- g.write ('memcpy(${tmpvar }.data, ' )
6472- if expr0 in [ast.CallExpr, ast.StructInit] {
6473- g.expr_with_opt (expr0 , type0 , fn_ret_type)
6474- g.write ('.data' )
6475- } else {
6476- g.expr (expr0 )
6477- }
6478- g.writeln (', sizeof(${styp }));' )
6479- } else {
6480- styp := g.base_type (fn_ret_type)
6481- g.write ('builtin___result_ok(&(${styp }[]) { ' )
6482- if ! fn_ret_type.is_ptr () && type0 .is_ptr () {
6483- if ! ((expr0 is ast.Ident && ! g.is_amp) || sym.kind == .interface ) {
6484- g.write ('*' )
6485- }
6486- }
6487- if fn_ret_type.has_flag (.option) {
6488- g.expr_with_opt (expr0 , type0 , fn_ret_type.clear_flag (.result))
6489- } else if return_sym.kind == .array_fixed && expr0 ! is ast.ArrayInit {
6490- info := return_sym.info as ast.ArrayFixed
6491- g.fixed_array_var_init (g.expr_string (expr0 ), expr0 .is_auto_deref_var (),
6492- info.elem_type, info.size)
6493- } else {
6494- g.expr_with_cast (expr0 , type0 , fn_ret_type.clear_flag (.result))
6495- }
6496- g.writeln (' }, (${result_name }*)(&${tmpvar }), sizeof(${styp }));' )
6497- }
6479+ if (fn_return_is_option && ! expr_type_is_opt && return_sym.name != option_name)
6480+ || (fn_return_is_result && ! expr_type_is_result && return_sym.name != result_name) {
6481+ g.expr_with_tmp_var (expr0 , type0 , fn_ret_type, tmpvar, false )
6482+ g.writeln ('' )
64986483 g.write_defer_stmts_when_needed (node.scope, true , node.pos)
64996484 if g.is_autofree {
65006485 g.detect_used_var_on_return (expr0 )
0 commit comments