From 16ef1d95fb724b7f973f9502cbde64d0ddee617b Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 27 May 2023 15:42:31 -0300 Subject: [PATCH] cgen: fix fixed array ret with anon fn (#18279) --- vlib/v/gen/c/cgen.v | 10 ++++--- vlib/v/parser/fn.v | 2 ++ vlib/v/tests/anon_fn_fixed_arr_test.v | 38 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/anon_fn_fixed_arr_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 606d98132c..ab23af6447 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1562,8 +1562,10 @@ pub fn (mut g Gen) write_fn_typesymbol_declaration(sym ast.TypeSymbol) { } else { '' } - - g.type_definitions.write_string('typedef ${g.typ(func.return_type)} (${msvc_call_conv}*${fn_name})(') + ret_typ := + if !func.return_type.has_flag(.option) && g.table.sym(func.return_type).kind == .array_fixed { '_v_' } else { '' } + + g.typ(func.return_type) + g.type_definitions.write_string('typedef ${ret_typ} (${msvc_call_conv}*${fn_name})(') for i, param in func.params { g.type_definitions.write_string(g.typ(param.typ)) if i < func.params.len - 1 { @@ -2441,7 +2443,9 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ } // no cast g.expr(expr) - if expr is ast.CallExpr && exp_sym.kind == .array_fixed { + if expr is ast.CallExpr && !(expr as ast.CallExpr).is_fn_var && !expected_type.has_flag(.option) + && exp_sym.kind == .array_fixed { + // it's non-option fixed array, requires accessing .ret_arr member to get the array g.write('.ret_arr') } } diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 966e2a6fa2..99397bd0f0 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -755,7 +755,9 @@ fn (mut p Parser) anon_fn() ast.AnonFn { if same_line { if (p.tok.kind.is_start_of_type() && (same_line || p.tok.kind != .lsbr)) || (same_line && p.tok.kind == .key_fn) { + p.inside_fn_return = true return_type = p.parse_type() + p.inside_fn_return = false return_type_pos = return_type_pos.extend(p.tok.pos()) } else if p.tok.kind != .lcbr { p.error_with_pos('expected return type, not ${p.tok} for anonymous function', diff --git a/vlib/v/tests/anon_fn_fixed_arr_test.v b/vlib/v/tests/anon_fn_fixed_arr_test.v new file mode 100644 index 0000000000..4acac56df5 --- /dev/null +++ b/vlib/v/tests/anon_fn_fixed_arr_test.v @@ -0,0 +1,38 @@ +struct Struct { + f fn () ?[2]int + g fn () [2]int +} + +fn test_struct_member() { + s := Struct{ + f: fn () ?[2]int { + return [1, 2]! + } + g: fn () [2]int { + return [1, 2]! + } + } + + mut a := s.f() + println(s.f()) + dump(a) + mut b := s.g() + println(s.g()) + dump(b) +} + +fn test_fn_var() { + mut h := fn () [2]int { + return [1, 2]! + } + mut i := fn () ?[2]int { + return [1, 2]! + } + + mut c := h() + println(h()) + dump(c) + mut d := i() + println(i()) + dump(d) +}