Skip to content

Commit 2a12104

Browse files
authored
cgen: include ast.ComptimeSelector in fixed array checks (fix #25767) (#25777)
1 parent e97bf8d commit 2a12104

2 files changed

Lines changed: 89 additions & 2 deletions

File tree

‎vlib/v/gen/c/assign.v‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
532532
unaliased_right_sym := g.table.final_sym(unwrapped_val_type)
533533
unaliased_left_sym := g.table.final_sym(g.unwrap_generic(var_type))
534534
is_fixed_array_var := unaliased_right_sym.kind == .array_fixed && val !is ast.ArrayInit
535-
&& (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.DumpExpr, ast.InfixExpr]
535+
&& (val in [ast.Ident, ast.IndexExpr, ast.CallExpr, ast.SelectorExpr, ast.ComptimeSelector, ast.DumpExpr, ast.InfixExpr]
536536
|| (val is ast.CastExpr && val.expr !is ast.ArrayInit)
537537
|| (val is ast.PrefixExpr && val.op == .arrow)
538538
|| (val is ast.UnsafeExpr && val.expr in [ast.SelectorExpr, ast.Ident, ast.CallExpr]))
@@ -568,7 +568,8 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
568568
} else {
569569
g.write('{${styp} _ = ')
570570
}
571-
if val in [ast.MatchExpr, ast.IfExpr] && unaliased_right_sym.info is ast.ArrayFixed {
571+
if (val in [ast.MatchExpr, ast.IfExpr, ast.ComptimeSelector] || is_fixed_array_var)
572+
&& unaliased_right_sym.info is ast.ArrayFixed {
572573
tmp_var := g.expr_with_var(val, var_type, false)
573574
g.fixed_array_var_init(tmp_var, false, unaliased_right_sym.info.elem_type,
574575
unaliased_right_sym.info.size)
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
struct StructWithFixedArrays {
2+
number u64
3+
bytes [8]u8
4+
floats [4]f32
5+
name string
6+
matrix [2][3]int
7+
}
8+
9+
fn collect_field_info[T](t T) []string {
10+
mut info := []string{}
11+
$for f in T.fields {
12+
v := t.$(f.name)
13+
info << '${f.name}: ${v}'
14+
}
15+
return info
16+
}
17+
18+
fn count_accessible_fields[T](t T) int {
19+
mut count := 0
20+
$for f in T.fields {
21+
_ := t.$(f.name)
22+
count++
23+
}
24+
return count
25+
}
26+
27+
fn test_fixed_array_field_access() {
28+
test := StructWithFixedArrays{
29+
number: 42
30+
bytes: [u8(1), 2, 3, 4, 5, 6, 7, 8]!
31+
floats: [f32(1.0), 2.0, 3.0, 4.0]!
32+
name: 'test'
33+
matrix: [[1, 2, 3]!, [4, 5, 6]!]!
34+
}
35+
36+
info := collect_field_info(test)
37+
38+
assert info.len == 5
39+
assert info[0].contains('number: 42')
40+
assert info[1].contains('bytes: [1, 2, 3, 4, 5, 6, 7, 8]')
41+
assert info[2].contains('floats: [1.0, 2.0, 3.0, 4.0]')
42+
assert info[3].contains('name: test')
43+
assert info[4].contains('matrix: [[1, 2, 3], [4, 5, 6]]')
44+
}
45+
46+
fn test_nested_fixed_arrays() {
47+
test := StructWithFixedArrays{
48+
number: 100
49+
bytes: [u8(10), 20, 30, 40, 50, 60, 70, 80]!
50+
floats: [f32(0.1), 0.2, 0.3, 0.4]!
51+
name: 'nested'
52+
matrix: [[10, 20, 30]!, [40, 50, 60]!]!
53+
}
54+
55+
assert count_accessible_fields(test) == 5
56+
}
57+
58+
fn test_fixed_array_comptime_iteration() {
59+
test := StructWithFixedArrays{
60+
number: 999
61+
bytes: [u8(0), 1, 2, 3, 4, 5, 6, 7]!
62+
floats: [f32(1.1), 2.2, 3.3, 4.4]!
63+
name: 'iteration'
64+
matrix: [[100, 200, 300]!, [400, 500, 600]!]!
65+
}
66+
67+
mut field_names := []string{}
68+
mut field_values := []string{}
69+
70+
$for f in StructWithFixedArrays.fields {
71+
field_names << f.name
72+
val := test.$(f.name)
73+
field_values << '${val}'
74+
}
75+
assert field_names.len == 5
76+
assert field_values.len == 5
77+
78+
assert 'number' in field_names
79+
assert 'bytes' in field_names
80+
assert 'floats' in field_names
81+
assert 'name' in field_names
82+
assert 'matrix' in field_names
83+
84+
assert field_values[0].contains('999')
85+
assert field_values[3].contains('iteration')
86+
}

0 commit comments

Comments
 (0)