diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v
index 795bf4260f..21e62e47a5 100644
--- a/vlib/v/ast/ast.v
+++ b/vlib/v/ast/ast.v
@@ -796,7 +796,7 @@ pub mut:
 }
 
 pub fn (i &Ident) var_info() IdentVar {
-	match mut i.info {
+	match i.info {
 		IdentVar {
 			return i.info
 		}
diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v
index 292107dbc1..834e153bd8 100644
--- a/vlib/v/ast/table.v
+++ b/vlib/v/ast/table.v
@@ -1640,7 +1640,7 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
 	mut nrt := ''
 	mut c_nrt := ''
 	ts := t.sym(typ)
-	match mut ts.info {
+	match ts.info {
 		Array {
 			mut elem_type := ts.info.elem_type
 			mut elem_sym := t.sym(elem_type)
@@ -1744,7 +1744,7 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
 		}
 		else {}
 	}
-	match mut ts.info {
+	match ts.info {
 		Struct {
 			mut info := ts.info
 			info.is_generic = false
diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v
index b48535e26e..f7ac0f3ac7 100644
--- a/vlib/v/checker/assign.v
+++ b/vlib/v/checker/assign.v
@@ -71,18 +71,18 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
 		return
 	}
 
-	for i, left in node.left {
-		if left is ast.CallExpr {
+	for i, mut left in node.left {
+		if mut left is ast.CallExpr {
 			// ban `foo() = 10`
 			c.error('cannot call function `${left.name}()` on the left side of an assignment',
 				left.pos)
-		} else if left is ast.PrefixExpr {
+		} else if mut left is ast.PrefixExpr {
 			// ban `*foo() = 10`
 			if left.right is ast.CallExpr && left.op == .mul {
 				c.error('cannot dereference a function call on the left side of an assignment, use a temporary variable',
 					left.pos)
 			}
-		} else if left is ast.IndexExpr {
+		} else if mut left is ast.IndexExpr {
 			if left.index is ast.RangeExpr {
 				c.error('cannot reassign using range expression on the left side of an assignment',
 					left.pos)
@@ -99,8 +99,8 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
 		}
 		if node.right_types.len < node.left.len { // first type or multi return types added above
 			old_inside_ref_lit := c.inside_ref_lit
-			if left is ast.Ident {
-				if left.info is ast.IdentVar {
+			if mut left is ast.Ident {
+				if mut left.info is ast.IdentVar {
 					c.inside_ref_lit = c.inside_ref_lit || left.info.share == .shared_t
 				}
 			}
diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v
index 1fae6276c1..355a89d86d 100644
--- a/vlib/v/checker/check_types.v
+++ b/vlib/v/checker/check_types.v
@@ -821,7 +821,7 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr
 				} else if arg_sym.kind in [.struct_, .interface_, .sum_type] {
 					mut generic_types := []ast.Type{}
 					mut concrete_types := []ast.Type{}
-					match mut arg_sym.info {
+					match arg_sym.info {
 						ast.Struct, ast.Interface, ast.SumType {
 							generic_types = arg_sym.info.generic_types
 							concrete_types = arg_sym.info.concrete_types
diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v
index 2ed709db80..228d2306f8 100644
--- a/vlib/v/checker/checker.v
+++ b/vlib/v/checker/checker.v
@@ -528,7 +528,7 @@ pub fn (mut c Checker) expand_iface_embeds(idecl &ast.InterfaceDecl, level int,
 }
 
 fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) {
-	match mut expr {
+	match expr {
 		ast.FloatLiteral {
 			if expr.val.f64() == 0.0 {
 				oper := if op_kind == .div { 'division' } else { 'modulo' }
@@ -1084,10 +1084,11 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
 
 // returns name and position of variable that needs write lock
 // also sets `is_changed` to true (TODO update the name to reflect this?)
-fn (mut c Checker) fail_if_immutable(expr ast.Expr) (string, token.Pos) {
+fn (mut c Checker) fail_if_immutable(expr_ ast.Expr) (string, token.Pos) {
 	mut to_lock := '' // name of variable that needs lock
 	mut pos := token.Pos{} // and its position
 	mut explicit_lock_needed := false
+	mut expr := unsafe { expr_ }
 	match mut expr {
 		ast.CastExpr {
 			// TODO
@@ -1878,7 +1879,8 @@ fn (mut c Checker) check_loop_label(label string, pos token.Pos) {
 	c.loop_label = label
 }
 
-fn (mut c Checker) stmt(node ast.Stmt) {
+fn (mut c Checker) stmt(node_ ast.Stmt) {
+	mut node := unsafe { node_ }
 	$if trace_checker ? {
 		ntype := typeof(node).replace('v.ast.', '')
 		eprintln('checking: ${c.file.path:-30} | pos: ${node.pos.line_str():-39} | node: $ntype | $node')
@@ -2178,7 +2180,7 @@ fn (mut c Checker) asm_stmt(mut stmt ast.AsmStmt) {
 }
 
 fn (mut c Checker) asm_arg(arg ast.AsmArg, stmt ast.AsmStmt, aliases []string) {
-	match mut arg {
+	match arg {
 		ast.AsmAlias {}
 		ast.AsmAddressing {
 			if arg.scale !in [-1, 1, 2, 4, 8] {
@@ -2449,12 +2451,13 @@ pub fn (mut c Checker) unwrap_generic(typ ast.Type) ast.Type {
 }
 
 // TODO node must be mut
-pub fn (mut c Checker) expr(node ast.Expr) ast.Type {
+pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type {
 	c.expr_level++
 	defer {
 		c.expr_level--
 	}
 
+	mut node := unsafe { node_ }
 	if c.expr_level > checker.expr_level_cutoff_limit {
 		c.error('checker: too many expr levels: $c.expr_level ', node.pos())
 		return ast.void_type
@@ -3090,7 +3093,7 @@ pub fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
 		if node.tok_kind == .assign && node.is_mut {
 			c.error('`mut` not allowed with `=` (use `:=` to declare a variable)', node.pos)
 		}
-		if obj := node.scope.find(node.name) {
+		if mut obj := node.scope.find(node.name) {
 			match mut obj {
 				ast.GlobalField {
 					node.kind = .global
@@ -3173,7 +3176,7 @@ pub fn (mut c Checker) ident(mut node ast.Ident) ast.Type {
 		else if !name.contains('.') && node.mod != 'builtin' {
 			name = '${node.mod}.$node.name'
 		}
-		if obj := c.file.global_scope.find(name) {
+		if mut obj := c.file.global_scope.find(name) {
 			match mut obj {
 				ast.ConstField {
 					if !(obj.is_pub || obj.mod == c.mod || c.pref.is_test) {
diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v
index 36cd435118..b6371783ff 100644
--- a/vlib/v/checker/match.v
+++ b/vlib/v/checker/match.v
@@ -23,6 +23,10 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
 	// we setting this here rather than at the end of the method
 	// since it is used in c.match_exprs() it saves checking twice
 	node.cond_type = ast.mktyp(cond_type)
+	if (node.cond is ast.Ident && (node.cond as ast.Ident).is_mut)
+		|| (node.cond is ast.SelectorExpr && (node.cond as ast.SelectorExpr).is_mut) {
+		c.fail_if_immutable(node.cond)
+	}
 	c.ensure_type_exists(node.cond_type, node.pos) or { return ast.void_type }
 	c.check_expr_opt_call(node.cond, cond_type)
 	cond_type_sym := c.table.sym(cond_type)
@@ -307,7 +311,7 @@ fn (mut c Checker) match_exprs(mut node ast.MatchExpr, cond_type_sym ast.TypeSym
 			}
 		}
 	} else {
-		match mut cond_type_sym.info {
+		match cond_type_sym.info {
 			ast.SumType {
 				for v in cond_type_sym.info.variants {
 					v_str := c.table.type_to_str(v)
diff --git a/vlib/v/checker/tests/match_mut_with_immutable_var_err.out b/vlib/v/checker/tests/match_mut_with_immutable_var_err.out
new file mode 100644
index 0000000000..2714c5bca7
--- /dev/null
+++ b/vlib/v/checker/tests/match_mut_with_immutable_var_err.out
@@ -0,0 +1,7 @@
+vlib/v/checker/tests/match_mut_with_immutable_var_err.vv:5:12: error: `i` is immutable, declare it with `mut` to make it mutable
+    3 | fn main() {
+    4 |     i := Int(0)
+    5 |     match mut i {
+      |               ^
+    6 |         int { i = 1 }
+    7 |         byte { i = 2 }
diff --git a/vlib/v/checker/tests/match_mut_with_immutable_var_err.vv b/vlib/v/checker/tests/match_mut_with_immutable_var_err.vv
new file mode 100644
index 0000000000..56a5760808
--- /dev/null
+++ b/vlib/v/checker/tests/match_mut_with_immutable_var_err.vv
@@ -0,0 +1,10 @@
+type Int = byte | int
+
+fn main() {
+	i := Int(0)
+	match mut i {
+		int { i = 1 }
+		byte { i = 2 }
+	}
+	println(i)
+}
diff --git a/vlib/v/fmt/fmt.v b/vlib/v/fmt/fmt.v
index 7d90e8ce8e..cee30af7df 100644
--- a/vlib/v/fmt/fmt.v
+++ b/vlib/v/fmt/fmt.v
@@ -505,7 +505,8 @@ fn stmt_is_single_line(stmt ast.Stmt) bool {
 
 //=== General Expr-related methods and helpers ===//
 
-pub fn (mut f Fmt) expr(node ast.Expr) {
+pub fn (mut f Fmt) expr(node_ ast.Expr) {
+	mut node := unsafe { node_ }
 	if f.is_debug {
 		eprintln('expr: ${node.pos():-42} | node: ${node.type_name():-20} | $node.str()')
 	}
diff --git a/vlib/v/gen/c/assert.v b/vlib/v/gen/c/assert.v
index 24f08d3d44..0d236f5807 100644
--- a/vlib/v/gen/c/assert.v
+++ b/vlib/v/gen/c/assert.v
@@ -107,7 +107,7 @@ fn (mut g Gen) gen_assert_metainfo(node ast.AssertStmt) string {
 	g.writeln('\t${metaname}.fn_name = ${ctoslit(fn_name)};')
 	metasrc := cnewlines(ctoslit(src))
 	g.writeln('\t${metaname}.src = $metasrc;')
-	match mut node.expr {
+	match node.expr {
 		ast.InfixExpr {
 			expr_op_str := ctoslit(node.expr.op.str())
 			expr_left_str := cnewlines(ctoslit(node.expr.left.str()))
diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v
index cba6fd9c9d..982a3cf3e8 100644
--- a/vlib/v/gen/c/auto_str_methods.v
+++ b/vlib/v/gen/c/auto_str_methods.v
@@ -178,7 +178,7 @@ fn (mut g Gen) final_gen_str(typ StrType) {
 		g.gen_str_for_option(typ.typ, styp, str_fn_name)
 		return
 	}
-	match mut sym.info {
+	match sym.info {
 		ast.Alias {
 			if sym.info.is_import {
 				g.gen_str_default(sym, styp, str_fn_name)
diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v
index 4aea8788f3..dd269e29f4 100644
--- a/vlib/v/gen/c/cgen.v
+++ b/vlib/v/gen/c/cgen.v
@@ -1122,7 +1122,7 @@ fn (mut g Gen) cc_type(typ ast.Type, is_prefix_struct bool) string {
 	sym := g.table.sym(g.unwrap_generic(typ))
 	mut styp := sym.cname
 	// TODO: this needs to be removed; cgen shouldn't resolve generic types (job of checker)
-	match mut sym.info {
+	match sym.info {
 		ast.Struct, ast.Interface, ast.SumType {
 			if sym.info.is_generic {
 				mut sgtyps := '_T'
@@ -2733,7 +2733,7 @@ fn (mut g Gen) map_fn_ptrs(key_typ ast.TypeSymbol) (string, string, string, stri
 	return hash_fn, key_eq_fn, clone_fn, free_fn
 }
 
-fn (mut g Gen) expr(node ast.Expr) {
+fn (mut g Gen) expr(node_ ast.Expr) {
 	// println('cgen expr() line_nr=$node.pos.line_nr')
 	old_discard_or_result := g.discard_or_result
 	old_is_void_expr_stmt := g.is_void_expr_stmt
@@ -2744,6 +2744,7 @@ fn (mut g Gen) expr(node ast.Expr) {
 		g.discard_or_result = false
 	}
 	// Note: please keep the type names in the match here in alphabetical order:
+	mut node := unsafe { node_ }
 	match mut node {
 		ast.ComptimeType {
 			g.error('g.expr(): Unhandled ComptimeType', node.pos)
@@ -4550,7 +4551,7 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) {
 		}
 		// sym := g.table.sym(typ)
 		mut name := sym.cname
-		match mut sym.info {
+		match sym.info {
 			ast.Struct {
 				if sym.info.is_generic {
 					continue
@@ -4724,7 +4725,7 @@ fn (g &Gen) sort_structs(typesa []&ast.TypeSymbol) []&ast.TypeSymbol {
 		}
 		// create list of deps
 		mut field_deps := []string{}
-		match mut sym.info {
+		match sym.info {
 			ast.ArrayFixed {
 				dep := g.table.sym(sym.info.elem_type).name
 				if dep in type_names {
@@ -5576,7 +5577,7 @@ static inline __shared__$interface_name ${shared_fn_name}(__shared__$cctype* x)
 				mut name := method.name
 				if inter_info.parent_type.has_flag(.generic) {
 					parent_sym := g.table.sym(inter_info.parent_type)
-					match mut parent_sym.info {
+					match parent_sym.info {
 						ast.Struct, ast.Interface, ast.SumType {
 							name = g.generic_fn_name(parent_sym.info.concrete_types, method.name,
 								false)
diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v
index 56b1c293fc..2e3c8ef03d 100644
--- a/vlib/v/gen/c/fn.v
+++ b/vlib/v/gen/c/fn.v
@@ -1443,7 +1443,7 @@ fn (mut g Gen) autofree_call_pregen(node ast.CallExpr) {
 			// We do not need to declare this variable again, so just generate `t = ...`
 			// instead of `string t = ...`, and we need to mark this variable as unused,
 			// so that it's freed after the call. (Used tmp arg vars are not freed to avoid double frees).
-			if x := scope.find(t) {
+			if mut x := scope.find(t) {
 				match mut x {
 					ast.Var { x.is_used = false }
 					else {}
@@ -1491,8 +1491,8 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
 	}
 	// g.doing_autofree_tmp = true
 	// g.write('/* postgen */')
-	scope := g.file.scope.innermost(node_pos)
-	for _, obj in scope.objects {
+	mut scope := g.file.scope.innermost(node_pos)
+	for _, mut obj in scope.objects {
 		match mut obj {
 			ast.Var {
 				// if var.typ == 0 {
diff --git a/vlib/v/gen/c/infix_expr.v b/vlib/v/gen/c/infix_expr.v
index 752aa9e470..d844cd277a 100644
--- a/vlib/v/gen/c/infix_expr.v
+++ b/vlib/v/gen/c/infix_expr.v
@@ -501,7 +501,7 @@ fn (mut g Gen) infix_expr_is_op(node ast.InfixExpr) {
 	if sym.kind == .interface_ {
 		g.write('_typ $cmp_op ')
 		// `_Animal_Dog_index`
-		sub_type := match mut node.right {
+		sub_type := match node.right {
 			ast.TypeNode { node.right.typ }
 			ast.None { g.table.type_idxs['None__'] }
 			else { ast.Type(0) }
diff --git a/vlib/v/gen/js/auto_str_methods.v b/vlib/v/gen/js/auto_str_methods.v
index 14c7fdf4ef..39fc79516d 100644
--- a/vlib/v/gen/js/auto_str_methods.v
+++ b/vlib/v/gen/js/auto_str_methods.v
@@ -59,7 +59,7 @@ fn (mut g JsGen) final_gen_str(typ StrType) {
 		g.gen_str_for_option(typ.typ, styp, str_fn_name)
 		return
 	}
-	match mut sym.info {
+	match sym.info {
 		ast.Alias {
 			if sym.info.is_import {
 				g.gen_str_default(sym, styp, str_fn_name)
diff --git a/vlib/v/gen/js/deep_copy.v b/vlib/v/gen/js/deep_copy.v
index b892d2f4ca..9e20095820 100644
--- a/vlib/v/gen/js/deep_copy.v
+++ b/vlib/v/gen/js/deep_copy.v
@@ -206,7 +206,7 @@ fn (mut g JsGen) final_gen_copy(typ StrType) {
 		}
 		else {}
 	}
-	match mut sym.info {
+	match sym.info {
 		ast.Alias {
 			g.gen_copy_for_alias(sym.info, styp, copy_fn_name)
 		}
diff --git a/vlib/v/gen/js/js.v b/vlib/v/gen/js/js.v
index b8ab23744e..33dc2d3e6b 100644
--- a/vlib/v/gen/js/js.v
+++ b/vlib/v/gen/js/js.v
@@ -641,8 +641,9 @@ fn (mut g JsGen) gen_alias_type_decl(node ast.AliasTypeDecl) {
 	g.writeln('function ${name}(val) { return val;  }')
 }
 
-fn (mut g JsGen) stmt_no_semi(node ast.Stmt) {
+fn (mut g JsGen) stmt_no_semi(node_ ast.Stmt) {
 	g.stmt_start_pos = g.out.len
+	mut node := unsafe { node_ }
 	match mut node {
 		ast.EmptyStmt {}
 		ast.AsmStmt {
@@ -744,8 +745,9 @@ fn (mut g JsGen) stmt_no_semi(node ast.Stmt) {
 	}
 }
 
-fn (mut g JsGen) stmt(node ast.Stmt) {
+fn (mut g JsGen) stmt(node_ ast.Stmt) {
 	g.stmt_start_pos = g.out.len
+	mut node := unsafe { node_ }
 	match mut node {
 		ast.EmptyStmt {}
 		ast.AsmStmt {
@@ -853,8 +855,9 @@ fn (mut g JsGen) stmt(node ast.Stmt) {
 	}
 }
 
-fn (mut g JsGen) expr(node ast.Expr) {
+fn (mut g JsGen) expr(node_ ast.Expr) {
 	// Note: please keep the type names in the match here in alphabetical order:
+	mut node := unsafe { node_ }
 	match mut node {
 		ast.ComptimeType {
 			verror('not yet implemented')
@@ -1128,7 +1131,7 @@ fn (mut g JsGen) gen_assert_metainfo(node ast.AssertStmt) string {
 	metasrc := src
 	g.writeln('${metaname}.src = "$metasrc"')
 
-	match mut node.expr {
+	match node.expr {
 		ast.InfixExpr {
 			expr_op_str := node.expr.op.str()
 			expr_left_str := node.expr.left.str()
@@ -1594,7 +1597,7 @@ fn (mut g JsGen) gen_expr_stmt_no_semi(it ast.ExprStmt) {
 fn (mut g JsGen) cc_type(typ ast.Type, is_prefix_struct bool) string {
 	sym := g.table.sym(g.unwrap_generic(typ))
 	mut styp := sym.cname.replace('>', '').replace('<', '')
-	match mut sym.info {
+	match sym.info {
 		ast.Struct, ast.Interface, ast.SumType {
 			if sym.info.is_generic {
 				mut sgtyps := '_T'
diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v
index 85e0dbc62c..9f047968db 100644
--- a/vlib/v/gen/native/amd64.v
+++ b/vlib/v/gen/native/amd64.v
@@ -1209,13 +1209,13 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
 	if node.left is ast.InfixExpr {
 		g.n_error('only simple expressions are supported right now (not more than 2 operands)')
 	}
-	match mut node.left {
+	match node.left {
 		ast.Ident {
 			g.mov_var_to_reg(.eax, g.get_var_offset(node.left.name))
 		}
 		else {}
 	}
-	if mut node.right is ast.Ident {
+	if node.right is ast.Ident {
 		var_offset := g.get_var_offset(node.right.name)
 		match node.op {
 			.plus { g.add8_var(.eax, var_offset) }
@@ -1409,9 +1409,9 @@ fn (mut g Gen) cjmp_op(op token.Kind) int {
 }
 
 fn (mut g Gen) condition(infix_expr ast.InfixExpr, neg bool) int {
-	match mut infix_expr.left {
+	match infix_expr.left {
 		ast.IntegerLiteral {
-			match mut infix_expr.right {
+			match infix_expr.right {
 				ast.IntegerLiteral {
 					// 3 < 4
 					a0 := infix_expr.left.val.int()
@@ -1435,7 +1435,7 @@ fn (mut g Gen) condition(infix_expr ast.InfixExpr, neg bool) int {
 			}
 		}
 		ast.Ident {
-			match mut infix_expr.right {
+			match infix_expr.right {
 				ast.IntegerLiteral {
 					// var < 4
 					lit := infix_expr.right as ast.IntegerLiteral
@@ -1515,7 +1515,7 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
 	infix_expr := node.cond as ast.InfixExpr
 	mut jump_addr := 0 // location of `jne *00 00 00 00*`
 	start := g.pos()
-	match mut infix_expr.left {
+	match infix_expr.left {
 		ast.Ident {
 			match infix_expr.right {
 				ast.Ident {
diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v
index e42b3d648d..e599b0278b 100644
--- a/vlib/v/gen/native/gen.v
+++ b/vlib/v/gen/native/gen.v
@@ -486,7 +486,7 @@ fn (mut g Gen) gen_forc_stmt(node ast.ForCStmt) {
 		match cond {
 			ast.InfixExpr {
 				// g.infix_expr(node.cond)
-				match mut cond.left {
+				match cond.left {
 					ast.Ident {
 						lit := cond.right as ast.IntegerLiteral
 						g.cmp_var(cond.left.name, lit.val.int())
diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v
index 26c659aedf..67e7447e74 100644
--- a/vlib/v/markused/walker.v
+++ b/vlib/v/markused/walker.v
@@ -96,7 +96,8 @@ pub fn (mut w Walker) mark_markused_globals() {
 	}
 }
 
-pub fn (mut w Walker) stmt(node ast.Stmt) {
+pub fn (mut w Walker) stmt(node_ ast.Stmt) {
+	mut node := unsafe { node_ }
 	match mut node {
 		ast.EmptyStmt {}
 		ast.AsmStmt {
@@ -215,7 +216,8 @@ fn (mut w Walker) exprs(exprs []ast.Expr) {
 	}
 }
 
-fn (mut w Walker) expr(node ast.Expr) {
+fn (mut w Walker) expr(node_ ast.Expr) {
+	mut node := unsafe { node_ }
 	match mut node {
 		ast.EmptyExpr {
 			// TODO make sure this doesn't happen
diff --git a/vlib/v/parser/assign.v b/vlib/v/parser/assign.v
index 0f6a28726c..9da40ed599 100644
--- a/vlib/v/parser/assign.v
+++ b/vlib/v/parser/assign.v
@@ -175,7 +175,8 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
 	mut has_cross_var := false
 	mut is_static := false
 	mut is_volatile := false
-	for i, lx in left {
+	for i, lx_ in left {
+		mut lx := unsafe { lx_ }
 		match mut lx {
 			ast.Ident {
 				if op == .decl_assign {
diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v
index b8ea460c8d..c4468d242b 100644
--- a/vlib/v/parser/parser.v
+++ b/vlib/v/parser/parser.v
@@ -3750,7 +3750,7 @@ fn (mut p Parser) rewind_scanner_to_current_token_in_new_mode() {
 
 // returns true if `varname` is known
 pub fn (mut p Parser) mark_var_as_used(varname string) bool {
-	if obj := p.scope.find(varname) {
+	if mut obj := p.scope.find(varname) {
 		match mut obj {
 			ast.Var {
 				obj.is_used = true
diff --git a/vlib/v/tests/sumtype_assign_test.v b/vlib/v/tests/sumtype_assign_test.v
index e44ae1b9a9..7b726f49b3 100644
--- a/vlib/v/tests/sumtype_assign_test.v
+++ b/vlib/v/tests/sumtype_assign_test.v
@@ -27,7 +27,7 @@ fn test_sumtype_assign() {
 		text: 'baz'
 	}
 	mut results := []string{}
-	for a in arr {
+	for mut a in arr {
 		match mut a {
 			Bar, Baz {
 				a.text = 'I am ' + a.text
diff --git a/vlib/v/transformer/transformer.v b/vlib/v/transformer/transformer.v
index c7032c62f0..6239237dfc 100644
--- a/vlib/v/transformer/transformer.v
+++ b/vlib/v/transformer/transformer.v
@@ -401,7 +401,7 @@ pub fn (mut t Transformer) expr_stmt_match_expr(mut node ast.MatchExpr) ast.Expr
 		for mut expr in branch.exprs {
 			expr = t.expr(mut expr)
 
-			match mut cond {
+			match cond {
 				ast.BoolLiteral {
 					if expr is ast.BoolLiteral {
 						if cond.val == (expr as ast.BoolLiteral).val {