From a8ea1f9d5020bd958357d1122ee6dd1bdb020db0 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Fri, 2 Jun 2023 04:55:08 -0300 Subject: [PATCH] cgen, checker, parser: fix fixed array with channel (#18315) --- vlib/v/checker/assign.v | 9 +++++++++ vlib/v/gen/c/assign.v | 1 + vlib/v/gen/c/cgen.v | 16 ++++++++++++---- vlib/v/parser/parse_type.v | 4 +++- vlib/v/parser/parser.v | 1 + 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 511844ca6e..586600a03a 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -188,6 +188,15 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { } else if mut right is ast.PrefixExpr { if right.op == .amp && right.right is ast.StructInit { right_type = c.expr(right) + } else if right.op == .arrow { + right_type = c.expr(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) + } } } else if mut right is ast.Ident { if right.kind == .function { diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index f9efbf977b..eac7b14647 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -353,6 +353,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) { is_fixed_array_var := unaliased_right_sym.kind == .array_fixed && val !is ast.ArrayInit && (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr] || (val is ast.CastExpr && (val as ast.CastExpr).expr !is ast.ArrayInit) + || (val is ast.PrefixExpr && (val as ast.PrefixExpr).op == .arrow) || (val is ast.UnsafeExpr && (val as ast.UnsafeExpr).expr is ast.Ident)) && !g.pref.translated g.is_assign_lhs = true diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index fc2044edbc..11fb37834d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1408,16 +1408,24 @@ pub fn (mut g Gen) write_typedef_types() { chan_inf := sym.chan_info() chan_elem_type := chan_inf.elem_type if !chan_elem_type.has_flag(.generic) { - el_stype := g.typ(chan_elem_type) + mut el_stype := g.typ(chan_elem_type) + is_fixed_arr := g.table.sym(chan_elem_type).kind == .array_fixed + 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 + } g.channel_definitions.writeln(' static inline ${el_stype} __${sym.cname}_popval(${sym.cname} ch) { ${el_stype} val; - sync__Channel_try_pop_priv(ch, &val, false); + sync__Channel_try_pop_priv(ch, ${val_arg_pop}, false); return val; }') g.channel_definitions.writeln(' -static inline void __${sym.cname}_pushval(${sym.cname} ch, ${el_stype} val) { - sync__Channel_try_push_priv(ch, &val, false); +static inline void __${sym.cname}_pushval(${sym.cname} ch, ${push_arg} val) { + sync__Channel_try_push_priv(ch, ${val_arg_push}, false); }') } } diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 2206c821b5..23562015db 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) + !is_option && (p.inside_fn_return || p.inside_chan_decl)) if elem_type.has_flag(.generic) { return ast.new_type(idx).set_flag(.generic) } @@ -162,8 +162,10 @@ fn (mut p Parser) parse_chan_type() ast.Type { } p.register_auto_import('sync') p.next() + p.inside_chan_decl = true is_mut := p.tok.kind == .key_mut elem_type := p.parse_type() + p.inside_chan_decl = false idx := p.table.find_or_register_chan(elem_type, is_mut) if elem_type.has_flag(.generic) { return ast.new_type(idx).set_flag(.generic) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index d38d35f3da..af9bc1f1fc 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -64,6 +64,7 @@ mut: inside_struct_attr_decl bool inside_map_init bool inside_orm bool + inside_chan_decl bool or_is_handled bool // ignore `or` in this expression builtin_mod bool // are we in the `builtin` module? mod string // current module name