diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v
index bf0f660f93..8fc31ee49a 100644
--- a/vlib/v/checker/checker.v
+++ b/vlib/v/checker/checker.v
@@ -42,8 +42,8 @@ pub mut:
 	global_names     []string
 	locked_names     []string // vars that are currently locked
 	rlocked_names    []string // vars that are currently read-locked
-	in_for_count     int // if checker is currently in an for loop
-	// checked_ident  string // to avoid infinit checker loops
+	in_for_count     int // if checker is currently in a for loop
+	// checked_ident  string // to avoid infinite checker loops
 	returns          bool
 	scope_returns    bool
 	mod              string // current module name
@@ -52,7 +52,7 @@ pub mut:
 	skip_flags       bool // should `#flag` and `#include` be skipped
 	cur_generic_type table.Type
 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
 	cur_orm_ts       table.TypeSymbol
 	error_details    []string
@@ -2364,17 +2364,13 @@ fn (mut c Checker) stmt(node ast.Stmt) {
 							node.cond.position())
 					}
 				}
-				// if node.val_is_mut {
-				// value_type = value_type.to_ptr()
-				// }
+				if node.val_is_mut {
+					value_type = value_type.to_ptr()
+				}
 				node.cond_type = typ
 				node.kind = sym.kind
 				node.val_type = value_type
-				if node.val_is_mut {
-					scope.update_var_type(node.val_var, value_type.to_ptr())
-				} else {
-					scope.update_var_type(node.val_var, value_type)
-				}
+				scope.update_var_type(node.val_var, value_type)
 			}
 			c.stmts(node.stmts)
 			c.in_for_count--
diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v
index b9d34d83d2..5dadd927b9 100644
--- a/vlib/v/fmt/fmt.v
+++ b/vlib/v/fmt/fmt.v
@@ -382,6 +382,9 @@ pub fn (mut f Fmt) stmt(node ast.Stmt) {
 				if it.key_var != '' {
 					f.write(', ')
 				}
+				if it.val_is_mut {
+					f.write('mut ')
+				}
 				f.write(it.val_var)
 			}
 			f.write(' in ')
diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v
index f988e84a45..79bc5626fb 100644
--- a/vlib/v/gen/cgen.v
+++ b/vlib/v/gen/cgen.v
@@ -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.writeln(' = ((voidptr*)$atmp${op_field}data)[$i];')
 			} 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)
diff --git a/vlib/v/tests/for_loops_test.v b/vlib/v/tests/for_loops_test.v
index 92c0c67e21..acc6fbbf08 100644
--- a/vlib/v/tests/for_loops_test.v
+++ b/vlib/v/tests/for_loops_test.v
@@ -57,11 +57,11 @@ fn test_for_char_in_map() {
 
 fn test_mut_for() {
 	/*
-	mut vals := [1,2,3]
+	mut vals := [1, 2, 3]
 	for mut val in vals {
 		(*val)++
 	}
-	assert vals == [2,3,4]
+	assert vals == [2, 3, 4]
 	println(vals)
 	*/
 }