checker: fix try_pop with fixed array (#18789)

This commit is contained in:
Felipe Pena 2023-07-05 20:34:22 -03:00 committed by GitHub
parent d851ecffb7
commit 8f7f2c8cf7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 21 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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)
}

View File

@ -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]!
}