From a9a94cfd51e01c6e0985c60049f1e82dbb7da1e2 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Thu, 13 Jul 2023 19:25:06 +0530 Subject: [PATCH] checker: add a separate error msg for `fail_if_immutable` for anon fns (#18854) --- vlib/v/checker/checker.v | 9 +++++++-- vlib/v/checker/tests/closure_copy_immutable_var_err.out | 7 +++++++ vlib/v/checker/tests/closure_copy_immutable_var_err.vv | 8 ++++++++ vlib/v/checker/tests/closure_immutable.out | 4 ++-- 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 vlib/v/checker/tests/closure_copy_immutable_var_err.out create mode 100644 vlib/v/checker/tests/closure_copy_immutable_var_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index a38a9b86c3..b09b8bf1e9 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -685,8 +685,13 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) { if mut expr.obj is ast.Var { if !expr.obj.is_mut && !c.pref.translated && !c.file.is_translated && !c.inside_unsafe { - c.error('`${expr.name}` is immutable, declare it with `mut` to make it mutable', - expr.pos) + if c.inside_anon_fn { + c.error('the closure copy of `${expr.name}` is immutable, declare it with `mut` to make it mutable', + expr.pos) + } else { + c.error('`${expr.name}` is immutable, declare it with `mut` to make it mutable', + expr.pos) + } } expr.obj.is_changed = true if expr.obj.typ.share() == .shared_t { diff --git a/vlib/v/checker/tests/closure_copy_immutable_var_err.out b/vlib/v/checker/tests/closure_copy_immutable_var_err.out new file mode 100644 index 0000000000..873ba5ecd8 --- /dev/null +++ b/vlib/v/checker/tests/closure_copy_immutable_var_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/closure_copy_immutable_var_err.vv:5:3: error: the closure copy of `name` is immutable, declare it with `mut` to make it mutable + 3 | + 4 | fn [name] () { + 5 | name = 'Ivan' + | ~~~~ + 6 | println(name) + 7 | }() diff --git a/vlib/v/checker/tests/closure_copy_immutable_var_err.vv b/vlib/v/checker/tests/closure_copy_immutable_var_err.vv new file mode 100644 index 0000000000..606535318b --- /dev/null +++ b/vlib/v/checker/tests/closure_copy_immutable_var_err.vv @@ -0,0 +1,8 @@ +fn main() { + mut name := 'John' + + fn [name] () { + name = 'Ivan' + println(name) + }() +} diff --git a/vlib/v/checker/tests/closure_immutable.out b/vlib/v/checker/tests/closure_immutable.out index bb93b27597..de0e7f52c6 100644 --- a/vlib/v/checker/tests/closure_immutable.out +++ b/vlib/v/checker/tests/closure_immutable.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/closure_immutable.vv:4:3: error: `a` is immutable, declare it with `mut` to make it mutable +vlib/v/checker/tests/closure_immutable.vv:4:3: error: the closure copy of `a` is immutable, declare it with `mut` to make it mutable 2 | a := 1 3 | f1 := fn [a] () { 4 | a++ @@ -12,7 +12,7 @@ vlib/v/checker/tests/closure_immutable.vv:7:16: error: original `a` is immutable | ^ 8 | a++ 9 | println(a) -vlib/v/checker/tests/closure_immutable.vv:13:3: error: `b` is immutable, declare it with `mut` to make it mutable +vlib/v/checker/tests/closure_immutable.vv:13:3: error: the closure copy of `b` is immutable, declare it with `mut` to make it mutable 11 | mut b := 2 12 | f3 := fn [b] () { 13 | b++