Skip to content

Commit

Permalink
checker: fix try_pop with fixed array (#18789)
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Jul 5, 2023
1 parent d851ecf commit 8f7f2c8
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 21 deletions.
15 changes: 2 additions & 13 deletions vlib/v/checker/assign.v
Expand Up @@ -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 = [
Expand Down Expand Up @@ -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 {
Expand Down
10 changes: 10 additions & 0 deletions vlib/v/checker/fn.v
Expand Up @@ -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 {
Expand Down
10 changes: 3 additions & 7 deletions vlib/v/gen/c/cgen.v
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/parser/parse_type.v
Expand Up @@ -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)
}
Expand Down
8 changes: 8 additions & 0 deletions 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]!
}

0 comments on commit 8f7f2c8

Please sign in to comment.