cgen: fix for_in_mut_val (fix #8087) (#8129)

pull/8159/head
yuyi 2021-01-17 12:32:34 +08:00 committed by GitHub
parent 3e44816e44
commit 9376c57a51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 1 deletions

View File

@ -64,6 +64,7 @@ mut:
inside_sql bool // to handle sql table fields pseudo variables
cur_orm_ts table.TypeSymbol
error_details []string
for_in_mut_val_name string
vmod_file_content string // needed for @VMOD_FILE, contents of the file, *NOT its path**
vweb_gen_types []table.Type // vweb route checks
prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then
@ -2493,7 +2494,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
assign_stmt.pos)
}
left_is_ptr := left_type.is_ptr() || left_sym.is_pointer()
if left_is_ptr {
if left_is_ptr && c.for_in_mut_val_name != left.str() {
if !c.inside_unsafe && assign_stmt.op !in [.assign, .decl_assign] {
// ptr op=
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', assign_stmt.pos)
@ -2996,7 +2997,13 @@ fn (mut c Checker) stmt(node ast.Stmt) {
}
}
c.check_loop_label(node.label, node.pos)
if node.val_is_mut {
c.for_in_mut_val_name = node.val_var
}
c.stmts(node.stmts)
if node.val_is_mut {
c.for_in_mut_val_name = ''
}
c.loop_label = prev_loop_label
c.in_for_count--
}

View File

@ -112,6 +112,7 @@ mut:
strs_to_free0 []string // strings.Builder
// strs_to_free []string // strings.Builder
inside_call bool
for_in_mul_val_name string
has_main bool
inside_const bool
comp_for_method string // $for method in T.methods {}
@ -1379,7 +1380,13 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
s := g.table.type_to_str(it.cond_type)
g.error('for in: unhandled symbol `$it.cond` of type `$s`', it.pos)
}
if it.val_is_mut {
g.for_in_mul_val_name = it.val_var
}
g.stmts(it.stmts)
if it.val_is_mut {
g.for_in_mul_val_name = ''
}
if it.label.len > 0 {
g.writeln('\t${it.label}__continue: {}')
}
@ -2002,6 +2009,9 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
g.prevent_sum_type_unwrapping_once = true
}
if !is_fixed_array_copy || is_decl {
if !is_decl && left is ast.Ident && g.for_in_mul_val_name == (left as ast.Ident).name {
g.write('*')
}
g.expr(left)
}
}

View File

@ -0,0 +1,12 @@
fn foo(mut arr []int) {
for _, mut j in arr {
j *= 2
}
}
fn test_for_in_mut_val() {
mut arr := [1, 2, 3]
foo(mut arr)
println(arr)
assert arr == [2, 4, 6]
}