Skip to content

Commit 3fdbfca

Browse files
authored
cgen: fix for in with mutable structs (#12368)
1 parent 639cbfa commit 3fdbfca

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

vlib/v/gen/c/cgen.v

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2165,7 +2165,11 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
21652165
g.writeln('\tif (${t_var}.state != 0) break;')
21662166
val := if node.val_var in ['', '_'] { g.new_tmp_var() } else { node.val_var }
21672167
val_styp := g.typ(node.val_type)
2168-
g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
2168+
if node.val_is_mut {
2169+
g.writeln('\t$val_styp* $val = ($val_styp*)${t_var}.data;')
2170+
} else {
2171+
g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
2172+
}
21692173
} else {
21702174
typ_str := g.table.type_to_str(node.cond_type)
21712175
g.error('for in: unhandled symbol `$node.cond` of type `$typ_str`', node.pos)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
struct Struct {
2+
mut:
3+
array [][]int
4+
}
5+
6+
fn (s Struct) rows() StructsRowIterator {
7+
return StructsRowIterator{
8+
array: s.array
9+
position: 0
10+
}
11+
}
12+
13+
struct StructsRowIterator {
14+
Struct
15+
mut:
16+
position int
17+
}
18+
19+
fn (mut s StructsRowIterator) next() ?[]int {
20+
if s.position >= s.array.len {
21+
return error('out of range')
22+
}
23+
defer {
24+
s.position++
25+
}
26+
return s.array[s.position]
27+
}
28+
29+
fn test_for_in_mut_struct_val() {
30+
mut s := Struct{
31+
array: [[1, 2, 3], [4, 5, 6]]
32+
}
33+
println(s)
34+
mut si := s.rows()
35+
println(si)
36+
37+
mut rets := []string{}
38+
for mut row in si {
39+
println(row)
40+
rets << '$row'
41+
}
42+
assert rets.len == 2
43+
assert rets[0] == '[1, 2, 3]'
44+
assert rets[1] == '[4, 5, 6]'
45+
}

0 commit comments

Comments
 (0)