1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

cgen: fix fixed array ret with anon fn (#18279)

This commit is contained in:
Felipe Pena 2023-05-27 15:42:31 -03:00 committed by GitHub
parent 6bfa6ec93c
commit 16ef1d95fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 3 deletions

View File

@ -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')
}
}

View File

@ -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',

View File

@ -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)
}