diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 57eb93db7571d6..90d7d992f84d85 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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 { diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index dd80469ea859cb..50137627160a9c 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -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()) } diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 6d3f92d3f10a3a..f8dabfc1e9a884 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -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('*') diff --git a/vlib/v/gen/c/struct.v b/vlib/v/gen/c/struct.v index 206d7b93f048d3..97ee42d04b2bbb 100644 --- a/vlib/v/gen/c/struct.v +++ b/vlib/v/gen/c/struct.v @@ -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) diff --git a/vlib/v/tests/assign/array_fixed_init_with_call_test.v b/vlib/v/tests/assign/array_fixed_init_with_call_test.v new file mode 100644 index 00000000000000..3737eb705c0b6c --- /dev/null +++ b/vlib/v/tests/assign/array_fixed_init_with_call_test.v @@ -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) +}