diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 75d85e5a3de799..91318e61bab8eb 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -33,12 +33,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { } right_type_sym := c.table.sym(right_type) // fixed array returns an struct, but when assigning it must be the array type - if right_type_sym.kind == .array_fixed - && (right_type_sym.info as ast.ArrayFixed).is_fn_ret { - info := right_type_sym.info as ast.ArrayFixed - right_type = c.table.find_or_register_array_fixed(info.elem_type, info.size, - info.size_expr, false) - } + right_type = c.cast_fixed_array_ret(right_type, right_type_sym) if i == 0 { right_first_type = right_type node.right_types = [ @@ -198,13 +193,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { right_type = c.expr(mut right) } else if right.op == .arrow { right_type = c.expr(mut right) - right_type_sym := c.table.sym(right_type) - if right_type_sym.kind == .array_fixed - && (right_type_sym.info as ast.ArrayFixed).is_fn_ret { - info := right_type_sym.info as ast.ArrayFixed - right_type = c.table.find_or_register_array_fixed(info.elem_type, - info.size, info.size_expr, false) - } + right_type = c.cast_fixed_array_ret(right_type, c.table.sym(right_type)) } } else if mut right is ast.Ident { if right.kind == .function { diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 96d72ed4ad39a2..5df0b49674d29f 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1511,6 +1511,16 @@ fn (mut c Checker) resolve_fn_generic_args(func ast.Fn, mut node ast.CallExpr) [ return concrete_types } +// cast_fixed_array_ret casts a ArrayFixed type created to return to a non returning one +fn (mut c Checker) cast_fixed_array_ret(typ ast.Type, sym ast.TypeSymbol) ast.Type { + if sym.kind == .array_fixed && (sym.info as ast.ArrayFixed).is_fn_ret { + info := sym.info as ast.ArrayFixed + return c.table.find_or_register_array_fixed(info.elem_type, info.size, info.size_expr, + false) + } + return typ +} + fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { left_type := c.expr(mut node.left) if left_type == ast.void_type { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index a5db6a4b3dfba9..1549a3d69fbb0e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1410,16 +1410,12 @@ pub fn (mut g Gen) write_typedef_types() { g.type_definitions.writeln('typedef chan ${sym.cname};') chan_inf := sym.chan_info() chan_elem_type := chan_inf.elem_type + is_fixed_arr := g.table.sym(chan_elem_type).kind == .array_fixed if !chan_elem_type.has_flag(.generic) { - mut el_stype := g.typ(chan_elem_type) - is_fixed_arr := g.table.sym(chan_elem_type).kind == .array_fixed + el_stype := if is_fixed_arr { '_v_' } else { '' } + g.typ(chan_elem_type) val_arg_pop := if is_fixed_arr { '&val.ret_arr' } else { '&val' } val_arg_push := if is_fixed_arr { 'val' } else { '&val' } - push_arg := if is_fixed_arr { - el_stype.trim_string_left('_v_') + '*' - } else { - el_stype - } + push_arg := el_stype + if is_fixed_arr { '*' } else { '' } g.channel_definitions.writeln(' static inline ${el_stype} __${sym.cname}_popval(${sym.cname} ch) { ${el_stype} val; diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index b72abb3e3dc009..41603629077819 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -73,7 +73,7 @@ fn (mut p Parser) parse_array_type(expecting token.Kind, is_option bool) ast.Typ p.error_with_pos('fixed size cannot be zero or negative', size_expr.pos()) } idx := p.table.find_or_register_array_fixed(elem_type, fixed_size, size_expr, - !is_option && (p.inside_fn_return || p.inside_chan_decl)) + !is_option && p.inside_fn_return) if elem_type.has_flag(.generic) { return ast.new_type(idx).set_flag(.generic) } diff --git a/vlib/v/tests/chan_fixed_test.v b/vlib/v/tests/chan_fixed_test.v new file mode 100644 index 00000000000000..9890c5625ebffc --- /dev/null +++ b/vlib/v/tests/chan_fixed_test.v @@ -0,0 +1,8 @@ +fn test_main() { + a := chan [2]int{cap: 10} + c := [1, 2]! + dump(a.try_push(&c)) + mut d := [0, 0]! + dump(a.try_pop(mut d)) + assert dump(d) == [1, 2]! +}