From 2ca3046bf84741b4ec66d1cfe0e6bb8c31741024 Mon Sep 17 00:00:00 2001 From: Turiiya <34311583+tobealive@users.noreply.github.com> Date: Tue, 13 Jun 2023 07:52:37 +0200 Subject: [PATCH] checker: disallow assigning mutable reference to immutable ParExpr (#18420) --- vlib/v/checker/assign.v | 15 ++++++++++----- ...mutable_reference_var_with_parenthesis_err.out | 7 +++++++ ...mmutable_reference_var_with_parenthesis_err.vv | 12 ++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.out create mode 100644 vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.vv diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 586600a03a..04101c2b2c 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -732,13 +732,18 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { c.expr(right_node.right) c.inside_ref_lit = old_inside_ref_lit if right_node.op == .amp { - if right_node.right is ast.Ident { - if right_node.right.obj is ast.Var { - v := right_node.right.obj + expr := if right_node.right is ast.ParExpr { + right_node.right.expr + } else { + right_node.right + } + if expr is ast.Ident { + if expr.obj is ast.Var { + v := expr.obj right_type0 = v.typ } - if !c.inside_unsafe && assigned_var.is_mut() && !right_node.right.is_mut() { - c.error('`${right_node.right.name}` is immutable, cannot have a mutable reference to it', + if !c.inside_unsafe && assigned_var.is_mut() && !expr.is_mut() { + c.error('`${expr.name}` is immutable, cannot have a mutable reference to it', right_node.pos) } } diff --git a/vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.out b/vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.out new file mode 100644 index 0000000000..be8c568c1d --- /dev/null +++ b/vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.vv:10:11: error: `a_char` is immutable, cannot have a mutable reference to it + 8 | + 9 | fn foo() { + 10 | mut c := &(a_char) + | ^ + 11 | println(c) + 12 | } diff --git a/vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.vv b/vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.vv new file mode 100644 index 0000000000..f92707982b --- /dev/null +++ b/vlib/v/checker/tests/assign_immutable_reference_var_with_parenthesis_err.vv @@ -0,0 +1,12 @@ +struct MyChar { + c string +} + +const a_char = MyChar{ + c: 'a' +} + +fn foo() { + mut c := &(a_char) + println(c) +}