Skip to content

Commit 076fae5

Browse files
authored
cgen,checker: fix array map anon fn return fixed array (fix #25928) (#25977)
1 parent dec7030 commit 076fae5

3 files changed

Lines changed: 33 additions & 1 deletion

File tree

vlib/v/checker/fn.v

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3512,7 +3512,17 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
35123512
// map/filter are supposed to have 1 arg only
35133513
mut arg_type := unaliased_left_type
35143514
for mut arg in node.args {
3515-
arg_type = c.check_expr_option_or_result_call(arg.expr, c.expr(mut arg.expr))
3515+
mut expr_type := c.expr(mut arg.expr)
3516+
if arg.expr is ast.AnonFn {
3517+
// fix anon fn when return is a fixed array
3518+
expr_sym := c.table.sym(expr_type)
3519+
info := expr_sym.info as ast.FnType
3520+
return_type_sym := c.table.sym(info.func.return_type)
3521+
if return_type_sym.kind == .array_fixed {
3522+
expr_type = c.cast_fixed_array_ret(info.func.return_type, return_type_sym)
3523+
}
3524+
}
3525+
arg_type = c.check_expr_option_or_result_call(arg.expr, expr_type)
35163526
}
35173527
if method_name == 'map' {
35183528
// eprintln('>>>>>>> map node.args[0].expr: ${node.args[0].expr}, left_type: ${left_type} | elem_typ: ${elem_typ} | arg_type: ${arg_type}')

vlib/v/gen/c/array.v

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
525525
} else {
526526
(ret_sym.info as ast.ArrayFixed).elem_type
527527
}
528+
ret_elem_sym := g.table.final_sym(ret_elem_type)
528529
mut ret_elem_styp := g.styp(ret_elem_type)
529530
inp_elem_type := if left_is_array {
530531
(inp_sym.info as ast.Array).elem_type
@@ -576,12 +577,20 @@ fn (mut g Gen) gen_array_map(node ast.CallExpr) {
576577
match mut expr {
577578
ast.AnonFn {
578579
g.write('${ret_elem_styp} ${tmp_map_expr_result_name} = ')
580+
if ret_elem_sym.kind == .array_fixed {
581+
// unpack fixed array return value
582+
g.writeln('{0};')
583+
g.write('memcpy(&${tmp_map_expr_result_name}, ')
584+
}
579585
if expr.inherited_vars.len > 0 {
580586
g.write_closure_fn(mut expr, var_name, closure_var)
581587
} else {
582588
g.gen_anon_fn_decl(mut expr)
583589
g.write('${expr.decl.name}(${var_name})')
584590
}
591+
if ret_elem_sym.kind == .array_fixed {
592+
g.write('.ret_arr, sizeof(${ret_elem_styp}))')
593+
}
585594
}
586595
ast.Ident {
587596
g.write('${ret_elem_styp} ${tmp_map_expr_result_name} = ')
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module main
2+
3+
fn test_array_map_anon_return_fixed_array() {
4+
lines := ['1,2', '3,4', '5,7']
5+
coords := lines.map(fn (line string) [2]int {
6+
xs, ys := line.split_once(',') or { panic('invalid input') }
7+
x := xs.int()
8+
y := ys.int()
9+
return [x, y]!
10+
})
11+
12+
assert coords == [[1, 2]!, [3, 4]!, [5, 7]!]
13+
}

0 commit comments

Comments
 (0)