From fa5cd93c5210aacfbb728c1235332555c5363d01 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 26 Oct 2024 19:25:52 +0800 Subject: [PATCH 1/4] checker: fix index expr that left is if expr --- vlib/v/checker/checker.v | 7 +++++++ .../tests/immutable_array_in_if_expr_index.out | 14 ++++++++++++++ .../tests/immutable_array_in_if_expr_index.vv | 6 ++++++ vlib/v/tests/indexexpr_with_if_expr_test.v | 7 +++++++ 4 files changed, 34 insertions(+) create mode 100644 vlib/v/checker/tests/immutable_array_in_if_expr_index.out create mode 100644 vlib/v/checker/tests/immutable_array_in_if_expr_index.vv create mode 100644 vlib/v/tests/indexexpr_with_if_expr_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 5688ab4278a2ea..b41629875ba170 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1006,6 +1006,13 @@ fn (mut c Checker) fail_if_immutable(mut expr ast.Expr) (string, token.Pos) { ast.InfixExpr { return '', expr.pos } + ast.IfExpr { + for mut branch in expr.branches { + mut last_expr := (branch.stmts.last() as ast.ExprStmt).expr + c.fail_if_immutable(mut last_expr) + } + return '', expr.pos + } else { if !expr.is_pure_literal() { c.error('unexpected expression `${expr.type_name()}`', expr.pos()) diff --git a/vlib/v/checker/tests/immutable_array_in_if_expr_index.out b/vlib/v/checker/tests/immutable_array_in_if_expr_index.out new file mode 100644 index 00000000000000..924921e5477ef2 --- /dev/null +++ b/vlib/v/checker/tests/immutable_array_in_if_expr_index.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/immutable_array_in_if_expr_index.vv:4:13: error: `array_a` is immutable, declare it with `mut` to make it mutable + 2 | array_a := [1, 2, 3] + 3 | array_b := [4, 5, 6] + 4 | (if true { array_a } else { array_b })[0] = 999 + | ~~~~~~~ + 5 | println(array_a) + 6 | } +vlib/v/checker/tests/immutable_array_in_if_expr_index.vv:4:30: error: `array_b` is immutable, declare it with `mut` to make it mutable + 2 | array_a := [1, 2, 3] + 3 | array_b := [4, 5, 6] + 4 | (if true { array_a } else { array_b })[0] = 999 + | ~~~~~~~ + 5 | println(array_a) + 6 | } diff --git a/vlib/v/checker/tests/immutable_array_in_if_expr_index.vv b/vlib/v/checker/tests/immutable_array_in_if_expr_index.vv new file mode 100644 index 00000000000000..a05ac803ca84e1 --- /dev/null +++ b/vlib/v/checker/tests/immutable_array_in_if_expr_index.vv @@ -0,0 +1,6 @@ +fn main() { + array_a := [1, 2, 3] + array_b := [4, 5, 6] + (if true { array_a } else { array_b })[0] = 999 + println(array_a) +} diff --git a/vlib/v/tests/indexexpr_with_if_expr_test.v b/vlib/v/tests/indexexpr_with_if_expr_test.v new file mode 100644 index 00000000000000..a84d2b592ffc88 --- /dev/null +++ b/vlib/v/tests/indexexpr_with_if_expr_test.v @@ -0,0 +1,7 @@ +fn test_indexexpr_with_if_expr() { + mut array_a := [1, 2, 3] + mut array_b := [4, 5, 6] + (if true { array_a } else { array_b })[0] = 999 + println(array_a) + assert array_a == [999, 2, 3] +} From 1ff4c7065594186050facc8f490b08c0ae247c25 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 26 Oct 2024 20:35:41 +0800 Subject: [PATCH 2/4] fmt indexexpr_with_if_expr_test.v --- vlib/v/tests/indexexpr_with_if_expr_test.v | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vlib/v/tests/indexexpr_with_if_expr_test.v b/vlib/v/tests/indexexpr_with_if_expr_test.v index a84d2b592ffc88..1208f09c044a7e 100644 --- a/vlib/v/tests/indexexpr_with_if_expr_test.v +++ b/vlib/v/tests/indexexpr_with_if_expr_test.v @@ -1,7 +1,11 @@ fn test_indexexpr_with_if_expr() { mut array_a := [1, 2, 3] mut array_b := [4, 5, 6] - (if true { array_a } else { array_b })[0] = 999 + (if true { + array_a + } else { + array_b + })[0] = 999 println(array_a) assert array_a == [999, 2, 3] } From c486aceb367c886e4a6a951d9e4cd2884e37e049 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 26 Oct 2024 20:46:44 +0800 Subject: [PATCH 3/4] fmt indexexpr_with_if_expr_test.v --- vlib/v/tests/indexexpr_with_if_expr_test.v | 1 + 1 file changed, 1 insertion(+) diff --git a/vlib/v/tests/indexexpr_with_if_expr_test.v b/vlib/v/tests/indexexpr_with_if_expr_test.v index 1208f09c044a7e..862779fbae0c75 100644 --- a/vlib/v/tests/indexexpr_with_if_expr_test.v +++ b/vlib/v/tests/indexexpr_with_if_expr_test.v @@ -1,6 +1,7 @@ fn test_indexexpr_with_if_expr() { mut array_a := [1, 2, 3] mut array_b := [4, 5, 6] + (if true { array_a } else { From b91da15c3833d0b44cb8252d5ef7f2a9a6ce0f0c Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 26 Oct 2024 22:07:56 +0800 Subject: [PATCH 4/4] fix error of reference non-lvalue --- vlib/v/gen/c/if.v | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vlib/v/gen/c/if.v b/vlib/v/gen/c/if.v index 3024918c0455e4..d973ec62585d07 100644 --- a/vlib/v/gen/c/if.v +++ b/vlib/v/gen/c/if.v @@ -6,8 +6,8 @@ module c import v.ast fn (mut g Gen) need_tmp_var_in_if(node ast.IfExpr) bool { - if node.is_expr && g.inside_ternary == 0 { - if g.is_autofree || node.typ.has_option_or_result() || node.is_comptime { + if node.is_expr && (g.inside_ternary == 0 || g.is_assign_lhs) { + if g.is_autofree || node.typ.has_option_or_result() || node.is_comptime || g.is_assign_lhs { return true } for branch in node.branches {