From 72ed673566f4fa3afea0977d3563d9e501395e1a Mon Sep 17 00:00:00 2001 From: x0r19x91 Date: Wed, 27 May 2020 17:37:03 +0530 Subject: [PATCH] builtin: array: fix slice cloning --- vlib/v/gen/fn.v | 22 ++++++++++++++++++++-- vlib/v/tests/array_slice_clone_test.v | 11 +++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/array_slice_clone_test.v diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 2c67455446..8bf36a5203 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -438,7 +438,23 @@ fn (mut g Gen) method_call(node ast.CallExpr) { g.write('*($return_type_str*)') } } - name := '${receiver_type_name}_$node.name'.replace('.', '__') + + mut name := '${receiver_type_name}_$node.name'.replace('.', '__') + // Check if expression is: arr[a..b].clone(), arr[a..].clone() + // if so, then instead of calling array_clone(&array_slice(...)) + // call array_clone_static(array_slice(...)) + mut is_range_slice := false + if node.receiver_type.is_ptr() && !node.left_type.is_ptr() { + if node.left is ast.IndexExpr { + idx := (node.left as ast.IndexExpr).index + if idx is ast.RangeExpr { + // expr is arr[range].clone() + // use array_clone_static instead of array_clone + name = '${receiver_type_name}_${node.name}_static'.replace('.', '__') + is_range_slice = true + } + } + } // if node.receiver_type != 0 { // g.write('/*${g.typ(node.receiver_type)}*/') // g.write('/*expr_type=${g.typ(node.left_type)} rec type=${g.typ(node.receiver_type)}*/') @@ -452,7 +468,9 @@ fn (mut g Gen) method_call(node ast.CallExpr) { // The receiver is a reference, but the caller provided a value // Add `&` automatically. // TODO same logic in call_args() - g.write('&') + if !is_range_slice { + g.write('&') + } } else if !node.receiver_type.is_ptr() && node.left_type.is_ptr() && node.name != 'str' { g.write('/*rec*/*') } diff --git a/vlib/v/tests/array_slice_clone_test.v b/vlib/v/tests/array_slice_clone_test.v new file mode 100644 index 0000000000..ec7065b26f --- /dev/null +++ b/vlib/v/tests/array_slice_clone_test.v @@ -0,0 +1,11 @@ +fn test_array_slice_clone() { + arr := [1, 2, 3, 4, 5] + cl := arr[1..].clone() + assert cl == [2, 3, 4, 5] +} + +fn test_array_slice_clone2() { + arr := [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + cl := arr[1..].clone()[2..].clone() + assert cl == [4, 5, 6, 7, 8, 9, 10] +}