checker, cgen: fix for_in_mut iterator val (#12563)

pull/12566/head
yuyi 2021-11-24 20:43:37 +08:00 committed by GitHub
parent cbf4a5b58c
commit 6f46fc2170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 3 deletions

View File

@ -3395,7 +3395,14 @@ pub fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
old_selector_expr := c.inside_selector_expr
c.inside_selector_expr = true
typ := c.expr(node.expr)
mut typ := c.expr(node.expr)
if node.expr.is_auto_deref_var() {
if mut node.expr is ast.Ident {
if mut node.expr.obj is ast.Var {
typ = node.expr.obj.typ
}
}
}
c.inside_selector_expr = old_selector_expr
c.using_new_err_struct = using_new_err_struct_save
if typ == ast.void_type_idx {
@ -4857,7 +4864,10 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) {
if next_fn.params.len != 1 {
c.error('iterator method `next()` must have 0 parameters', node.cond.position())
}
val_type := next_fn.return_type.clear_flag(.optional)
mut val_type := next_fn.return_type.clear_flag(.optional)
if node.val_is_mut {
val_type = val_type.ref()
}
node.cond_type = typ
node.kind = sym.kind
node.val_type = val_type

View File

@ -2183,7 +2183,7 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
val := if node.val_var in ['', '_'] { g.new_tmp_var() } else { node.val_var }
val_styp := g.typ(node.val_type)
if node.val_is_mut {
g.writeln('\t$val_styp* $val = ($val_styp*)${t_var}.data;')
g.writeln('\t$val_styp $val = ($val_styp)${t_var}.data;')
} else {
g.writeln('\t$val_styp $val = *($val_styp*)${t_var}.data;')
}

View File

@ -0,0 +1,50 @@
const (
packets = {
0: &Packet{
pid: 2
}
1: &Packet{
pid: 1
}
}
)
struct Packet {
pid int
handle fn () string
restricted bool
}
struct Reader {
foo int
bar string
mut:
index int
}
fn (mut p Reader) next() ?&Packet {
if p.index + 1 > packets.len {
return error('')
}
if p.index !in packets {
return error('')
}
p.index++
return packets[p.index - 1]
}
fn test_for_in_mut_interator_val() {
r := Reader{}
mut rets := []string{}
for mut packet in r {
println(packet.pid)
rets << '$packet.pid'
}
println(rets)
assert rets.len == 2
assert rets[0] == '2'
assert rets[1] == '1'
}