From 9d3bef15e43c7ae3a43205a4c386f16ac09d4524 Mon Sep 17 00:00:00 2001 From: Turiiya <34311583+ttytm@users.noreply.github.com> Date: Thu, 25 Apr 2024 01:14:42 +0200 Subject: [PATCH] checker: turn array assign warning into error (#21341) --- vlib/v/checker/assign.v | 22 +++++-------------- vlib/v/checker/tests/array_assign_err.out | 2 +- .../checker/tests/array_or_map_assign_err.out | 7 ------ 3 files changed, 6 insertions(+), 25 deletions(-) diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 52f1eda91..9c766c6cc 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -498,26 +498,14 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { left_sym := c.table.sym(left_type_unwrapped) right_sym := c.table.sym(right_type_unwrapped) - old_assign_error_condition := left_sym.kind == .array && !c.inside_unsafe - && node.op in [.assign, .decl_assign] && right_sym.kind == .array && left is ast.Ident - && !left.is_blank_ident() && right is ast.Ident - if old_assign_error_condition { - // Do not allow `a = b`, only `a = b.clone()` - c.error('use `array2 ${node.op.str()} array1.clone()` instead of `array2 ${node.op.str()} array1` (or use `unsafe`)', - node.pos) - } - // Do not allow `a = val.array_field`, only `a = val.array_field.clone()` - // TODO: turn this warning into an error after 2022/09/24 - // TODO: and remove the less strict check from above. if left_sym.kind == .array && !c.inside_unsafe && right_sym.kind == .array && left is ast.Ident && !left.is_blank_ident() && right in [ast.Ident, ast.SelectorExpr] && ((node.op == .decl_assign && left.is_mut) || node.op == .assign) { - // no point to show the notice, if the old error was already shown: - if !old_assign_error_condition { - mut_str := if node.op == .decl_assign { 'mut ' } else { '' } - c.warn('use `${mut_str}array2 ${node.op.str()} array1.clone()` instead of `${mut_str}array2 ${node.op.str()} array1` (or use `unsafe`)', - node.pos) - } + // Do not allow direct array assignments outside unsafe. + // E.g.: `a2 = a1` wants `a2 = a1.clone()`, `a = val.arr_field` wants `a = val.arr_field.clone()` + mut_str := if node.op == .decl_assign { 'mut ' } else { '' } + c.error('use `${mut_str}array2 ${node.op.str()} array1.clone()` instead of `${mut_str}array2 ${node.op.str()} array1` (or use `unsafe`)', + node.pos) } if left_sym.kind == .array && right_sym.kind == .array { right_info := right_sym.info as ast.Array diff --git a/vlib/v/checker/tests/array_assign_err.out b/vlib/v/checker/tests/array_assign_err.out index f68603df2..a6f69cf58 100644 --- a/vlib/v/checker/tests/array_assign_err.out +++ b/vlib/v/checker/tests/array_assign_err.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/array_assign_err.vv:8:8: warning: use `mut array2 := array1.clone()` instead of `mut array2 := array1` (or use `unsafe`) +vlib/v/checker/tests/array_assign_err.vv:8:8: error: use `mut array2 := array1.clone()` instead of `mut array2 := array1` (or use `unsafe`) 6 | fn main() { 7 | a := Dumb{[1, 2, 3]} 8 | mut b := a.v // I expect a compiler error diff --git a/vlib/v/checker/tests/array_or_map_assign_err.out b/vlib/v/checker/tests/array_or_map_assign_err.out index c1788de34..853e2fc78 100644 --- a/vlib/v/checker/tests/array_or_map_assign_err.out +++ b/vlib/v/checker/tests/array_or_map_assign_err.out @@ -1,10 +1,3 @@ -vlib/v/checker/tests/array_or_map_assign_err.vv:3:5: error: use `array2 := array1.clone()` instead of `array2 := array1` (or use `unsafe`) - 1 | fn main() { - 2 | a1 := [1, 2, 3] - 3 | a2 := a1 - | ~~ - 4 | mut a3 := []int{} - 5 | a3 = a1 vlib/v/checker/tests/array_or_map_assign_err.vv:5:5: error: use `array2 = array1.clone()` instead of `array2 = array1` (or use `unsafe`) 3 | a2 := a1 4 | mut a3 := []int{} -- 2.39.5