Skip to content

Commit

Permalink
cgen, checker: fix codegen for fixed array initialization with a fn c…
Browse files Browse the repository at this point in the history
…all (fix #22887) (#22891)
  • Loading branch information
felipensp authored Nov 18, 2024
1 parent 3bf459c commit 73786b8
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 11 deletions.
19 changes: 10 additions & 9 deletions vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -1548,15 +1548,16 @@ pub:
has_init bool
has_index bool // true if temp variable index is used
pub mut:
exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array
len_expr Expr // len: expr
cap_expr Expr // cap: expr
init_expr Expr // init: expr
expr_types []Type // [Dog, Cat] // also used for interface_types
elem_type Type // element type
init_type Type // init: value type
typ Type // array type
alias_type Type // alias type
exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array
len_expr Expr // len: expr
cap_expr Expr // cap: expr
init_expr Expr // init: expr
expr_types []Type // [Dog, Cat] // also used for interface_types
elem_type Type // element type
init_type Type // init: value type
typ Type // array type
alias_type Type // alias type
has_callexpr bool // has expr which needs tmp var to initialize it
}

pub struct ArrayDecompose {
Expand Down
9 changes: 8 additions & 1 deletion vlib/v/checker/containers.v
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,14 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
}
}
for i, mut expr in node.exprs {
typ := c.check_expr_option_or_result_call(expr, c.expr(mut expr))
mut typ := c.check_expr_option_or_result_call(expr, c.expr(mut expr))
if expr is ast.CallExpr {
ret_sym := c.table.sym(typ)
if ret_sym.kind == .array_fixed {
typ = c.cast_fixed_array_ret(typ, ret_sym)
}
node.has_callexpr = true
}
if typ == ast.void_type {
c.error('invalid void array element type', expr.pos())
}
Expand Down
5 changes: 5 additions & 0 deletions vlib/v/gen/c/array.v
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st
elem_info := elem_sym.array_fixed_info()
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
elem_info.elem_type, elem_info.size)
} else if elem_sym.kind == .array_fixed && expr is ast.CallExpr
&& g.table.final_sym(expr.return_type).kind == .array_fixed {
elem_info := elem_sym.array_fixed_info()
tmp_var := g.expr_with_var(expr, node.expr_types[i], node.expr_types[i])
g.fixed_array_var_init(tmp_var, false, elem_info.elem_type, elem_info.size)
} else {
if expr.is_auto_deref_var() {
g.write('*')
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/gen/c/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua
tmp_var := g.expr_with_var(sfield.expr, sfield.typ, sfield.expected_type)
g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type,
field_unwrap_sym.info.size)
} else if sfield.expr.exprs.len > 0 && sfield.expr.exprs.any(it is ast.CallExpr) {
} else if sfield.expr.has_callexpr {
tmp_var := g.expr_with_fixed_array(sfield.expr, sfield.typ, sfield.expected_type)
g.fixed_array_var_init(tmp_var, false, field_unwrap_sym.info.elem_type,
field_unwrap_sym.info.size)
Expand Down
23 changes: 23 additions & 0 deletions vlib/v/tests/assign/array_fixed_init_with_call_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module main

import math.vec

type Vec4 = vec.Vec4[f32]

fn (v Vec4) to_array() [4]f32 {
return [v.x, v.y, v.z, v.w]!
}

fn test_main() {
v := Vec4{1, 2, 3, 4}
_ := [
v.to_array(),
]!
u := [
v.to_array(),
]!
assert u[0][0] == f32(1)
assert u[0][1] == f32(2)
assert u[0][2] == f32(3)
assert u[0][3] == f32(4)
}

0 comments on commit 73786b8

Please sign in to comment.