checker/fmt: `for mut val` fixes

pull/6616/head
Alexander Medvednikov 2020-10-14 12:49:55 +02:00
parent ed7e306adc
commit ea09bd5e45
4 changed files with 18 additions and 14 deletions

View File

@ -42,8 +42,8 @@ pub mut:
global_names []string global_names []string
locked_names []string // vars that are currently locked locked_names []string // vars that are currently locked
rlocked_names []string // vars that are currently read-locked rlocked_names []string // vars that are currently read-locked
in_for_count int // if checker is currently in an for loop in_for_count int // if checker is currently in a for loop
// checked_ident string // to avoid infinit checker loops // checked_ident string // to avoid infinite checker loops
returns bool returns bool
scope_returns bool scope_returns bool
mod string // current module name mod string // current module name
@ -52,7 +52,7 @@ pub mut:
skip_flags bool // should `#flag` and `#include` be skipped skip_flags bool // should `#flag` and `#include` be skipped
cur_generic_type table.Type cur_generic_type table.Type
mut: mut:
expr_level int // to avoid infinit recursion segfaults due to compiler bugs expr_level int // to avoid infinite recursion segfaults due to compiler bugs
inside_sql bool // to handle sql table fields pseudo variables inside_sql bool // to handle sql table fields pseudo variables
cur_orm_ts table.TypeSymbol cur_orm_ts table.TypeSymbol
error_details []string error_details []string
@ -2364,17 +2364,13 @@ fn (mut c Checker) stmt(node ast.Stmt) {
node.cond.position()) node.cond.position())
} }
} }
// if node.val_is_mut { if node.val_is_mut {
// value_type = value_type.to_ptr() value_type = value_type.to_ptr()
// } }
node.cond_type = typ node.cond_type = typ
node.kind = sym.kind node.kind = sym.kind
node.val_type = value_type node.val_type = value_type
if node.val_is_mut { scope.update_var_type(node.val_var, value_type)
scope.update_var_type(node.val_var, value_type.to_ptr())
} else {
scope.update_var_type(node.val_var, value_type)
}
} }
c.stmts(node.stmts) c.stmts(node.stmts)
c.in_for_count-- c.in_for_count--

View File

@ -382,6 +382,9 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
if it.key_var != '' { if it.key_var != '' {
f.write(', ') f.write(', ')
} }
if it.val_is_mut {
f.write('mut ')
}
f.write(it.val_var) f.write(it.val_var)
} }
f.write(' in ') f.write(' in ')

View File

@ -1070,7 +1070,12 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var)) g.write_fn_ptr_decl(val_sym.info as table.FnType, c_name(it.val_var))
g.writeln(' = ((voidptr*)$atmp${op_field}data)[$i];') g.writeln(' = ((voidptr*)$atmp${op_field}data)[$i];')
} else { } else {
g.writeln('\t$styp ${c_name(it.val_var)} = (($styp*)$atmp${op_field}data)[$i];') // If val is mutable (pointer behind the scenes), we need to generate
// `int* val = ((int*)arr.data)[i];`
// instead of
// `int* val = ((int**)arr.data)[i];`
styp_right := if it.val_is_mut { styp } else { styp + '*' }
g.writeln('\t$styp ${c_name(it.val_var)} = (($styp_right)$atmp${op_field}data)[$i];')
} }
} }
g.stmts(it.stmts) g.stmts(it.stmts)

View File

@ -57,11 +57,11 @@ fn test_for_char_in_map() {
fn test_mut_for() { fn test_mut_for() {
/* /*
mut vals := [1,2,3] mut vals := [1, 2, 3]
for mut val in vals { for mut val in vals {
(*val)++ (*val)++
} }
assert vals == [2,3,4] assert vals == [2, 3, 4]
println(vals) println(vals)
*/ */
} }