cgen: fix `for in` with mutable structs (#12368)

pull/12369/head
yuyi 2021-11-02 23:40:13 +08:00 committed by GitHub
parent 639cbfa0d1
commit 3fdbfca202
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 1 deletions

View File

@ -2165,7 +2165,11 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
g.writeln('\tif (${t_var}.state != 0) break;')
val := if node.val_var in ['', '_'] { g.new_tmp_var() } else { node.val_var }
val_styp := g.typ(node.val_type)
g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
if node.val_is_mut {
g.writeln('\t$val_styp* $val = ($val_styp*)${t_var}.data;')
} else {
g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
}
} else {
typ_str := g.table.type_to_str(node.cond_type)
g.error('for in: unhandled symbol `$node.cond` of type `$typ_str`', node.pos)

View File

@ -0,0 +1,45 @@
struct Struct {
mut:
array [][]int
}
fn (s Struct) rows() StructsRowIterator {
return StructsRowIterator{
array: s.array
position: 0
}
}
struct StructsRowIterator {
Struct
mut:
position int
}
fn (mut s StructsRowIterator) next() ?[]int {
if s.position >= s.array.len {
return error('out of range')
}
defer {
s.position++
}
return s.array[s.position]
}
fn test_for_in_mut_struct_val() {
mut s := Struct{
array: [[1, 2, 3], [4, 5, 6]]
}
println(s)
mut si := s.rows()
println(si)
mut rets := []string{}
for mut row in si {
println(row)
rets << '$row'
}
assert rets.len == 2
assert rets[0] == '[1, 2, 3]'
assert rets[1] == '[4, 5, 6]'
}