Skip to content

Commit 6f46fc2

Browse files
authored
checker, cgen: fix for_in_mut iterator val (#12563)
1 parent cbf4a5b commit 6f46fc2

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

vlib/v/checker/checker.v

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3395,7 +3395,14 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
33953395

33963396
old_selector_expr := c.inside_selector_expr
33973397
c.inside_selector_expr = true
3398-
typ := c.expr(node.expr)
3398+
mut typ := c.expr(node.expr)
3399+
if node.expr.is_auto_deref_var() {
3400+
if mut node.expr is ast.Ident {
3401+
if mut node.expr.obj is ast.Var {
3402+
typ = node.expr.obj.typ
3403+
}
3404+
}
3405+
}
33993406
c.inside_selector_expr = old_selector_expr
34003407
c.using_new_err_struct = using_new_err_struct_save
34013408
if typ == ast.void_type_idx {
@@ -4857,7 +4864,10 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
48574864
if next_fn.params.len != 1 {
48584865
c.error('iterator method `next()` must have 0 parameters', node.cond.position())
48594866
}
4860-
val_type := next_fn.return_type.clear_flag(.optional)
4867+
mut val_type := next_fn.return_type.clear_flag(.optional)
4868+
if node.val_is_mut {
4869+
val_type = val_type.ref()
4870+
}
48614871
node.cond_type = typ
48624872
node.kind = sym.kind
48634873
node.val_type = val_type

vlib/v/gen/c/cgen.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,7 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
21832183
val := if node.val_var in ['', '_'] { g.new_tmp_var() } else { node.val_var }
21842184
val_styp := g.typ(node.val_type)
21852185
if node.val_is_mut {
2186-
g.writeln('\t$val_styp* $val = ($val_styp*)${t_var}.data;')
2186+
g.writeln('\t$val_styp $val = ($val_styp)${t_var}.data;')
21872187
} else {
21882188
g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
21892189
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const (
2+
packets = {
3+
0: &Packet{
4+
pid: 2
5+
}
6+
1: &Packet{
7+
pid: 1
8+
}
9+
}
10+
)
11+
12+
struct Packet {
13+
pid int
14+
handle fn () string
15+
restricted bool
16+
}
17+
18+
struct Reader {
19+
foo int
20+
bar string
21+
mut:
22+
index int
23+
}
24+
25+
fn (mut p Reader) next() ?&Packet {
26+
if p.index + 1 > packets.len {
27+
return error('')
28+
}
29+
if p.index !in packets {
30+
return error('')
31+
}
32+
33+
p.index++
34+
return packets[p.index - 1]
35+
}
36+
37+
fn test_for_in_mut_interator_val() {
38+
r := Reader{}
39+
mut rets := []string{}
40+
41+
for mut packet in r {
42+
println(packet.pid)
43+
rets << '$packet.pid'
44+
}
45+
46+
println(rets)
47+
assert rets.len == 2
48+
assert rets[0] == '2'
49+
assert rets[1] == '1'
50+
}

0 commit comments

Comments
 (0)