builtin: array: fix slice cloning

pull/5073/head
x0r19x91 2020-05-27 17:37:03 +05:30 committed by GitHub
parent 6ca53d7b39
commit 72ed673566
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 2 deletions

View File

@ -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*/*')
}

View File

@ -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]
}