Skip to content

Commit

Permalink
cgen: allow alias to array fixed to be initialized like [n]int{} (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Jul 2, 2024
1 parent c9c41af commit 81b095b
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 10 deletions.
8 changes: 5 additions & 3 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -1537,7 +1537,8 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
}
field_name := node.field_name
sym := c.table.sym(typ)
if (typ.has_flag(.variadic) || sym.kind == .array_fixed) && field_name == 'len' {
final_sym := c.table.final_sym(typ)
if (typ.has_flag(.variadic) || final_sym.kind == .array_fixed) && field_name == 'len' {
node.typ = ast.int_type
return ast.int_type
}
Expand Down Expand Up @@ -2825,8 +2826,9 @@ pub fn (mut c Checker) expr(mut node ast.Expr) ast.Type {

unwrapped_expr_type := c.unwrap_generic(node.expr_type)
tsym := c.table.sym(unwrapped_expr_type)
if tsym.kind == .array_fixed {
info := tsym.info as ast.ArrayFixed
tsym_final := c.table.final_sym(unwrapped_expr_type)
if tsym_final.kind == .array_fixed {
info := tsym_final.info as ast.ArrayFixed
if !info.is_fn_ret {
// for dumping fixed array we must register the fixed array struct to return from function
c.table.find_or_register_array_fixed(info.elem_type, info.size, info.size_expr,
Expand Down
14 changes: 10 additions & 4 deletions vlib/v/checker/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -554,10 +554,16 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
c.error('unknown struct: ${type_sym.name}', node.pos)
return ast.void_type
}
if sym.kind == .struct_ {
info = sym.info as ast.Struct
} else {
c.error('alias type name: ${sym.name} is not struct type', node.pos)
match sym.kind {
.struct_ {
info = sym.info as ast.Struct
}
.array, .array_fixed {
// we do allow []int{}, [10]int{}
}
else {
c.error('alias type name: ${sym.name} is not struct type', node.pos)
}
}
} else {
info = type_sym.info as ast.Struct
Expand Down
5 changes: 3 additions & 2 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -3890,11 +3890,12 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
opt_base_typ := g.base_type(node.expr_type)
g.write('(*(${opt_base_typ}*)')
}
if sym.kind == .array_fixed {
final_sym := g.table.final_sym(g.unwrap_generic(node.expr_type))
if final_sym.kind == .array_fixed {
if node.field_name != 'len' {
g.error('field_name should be `len`', node.pos)
}
info := sym.info as ast.ArrayFixed
info := final_sym.info as ast.ArrayFixed
g.write('${info.size}')
return
} else if sym.kind == .chan && (node.field_name == 'len' || node.field_name == 'closed') {
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/gen/c/for.v
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ fn (mut g Gen) for_in_stmt(node_ ast.ForInStmt) {
cond_var = g.expr_string(node.cond)
}
idx := if node.key_var in ['', '_'] { g.new_tmp_var() } else { node.key_var }
cond_sym := g.table.sym(node.cond_type)
cond_sym := g.table.final_sym(node.cond_type)
info := cond_sym.info as ast.ArrayFixed
g.writeln('for (int ${idx} = 0; ${idx} != ${info.size}; ++${idx}) {')
if node.val_var != '_' {
Expand Down
19 changes: 19 additions & 0 deletions vlib/v/tests/alias_fixed_arr_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
type MyArray = [10]int
type MyArray2 = []int

fn test_main() {
a := MyArray{}

assert dump(a.len) == 10

mut count := 0
for w in a {
dump(w)
count++
}
assert count == 10

b := MyArray2{}
z := dump(b)
assert z.len == 0
}

0 comments on commit 81b095b

Please sign in to comment.