array: fix array_clone (fix #8220) (#8238)

pull/8236/head
yuyi 2021-01-21 17:17:00 +08:00 committed by GitHub
parent f059a9e96c
commit 242c5760f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 3 deletions

View File

@ -346,17 +346,25 @@ pub fn (a &array) clone() array {
// Recursively clone-generated elements if array element is array type
size_of_array := int(sizeof(array))
if a.element_size == size_of_array {
mut is_elem_array := true
for i in 0 .. a.len {
ar := array{}
unsafe { C.memcpy(&ar, a.get_unsafe(i), size_of_array) }
if ar.len > ar.cap || ar.cap <= 0 || ar.element_size <= 0 {
is_elem_array = false
break
}
ar_clone := ar.clone()
unsafe { arr.set_unsafe(i, &ar_clone) }
}
} else {
if !isnil(a.data) {
unsafe { C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size) }
if is_elem_array {
return arr
}
}
if !isnil(a.data) {
unsafe { C.memcpy(byteptr(arr.data), a.data, a.cap * a.element_size) }
}
return arr
}

View File

@ -1343,3 +1343,19 @@ fn test_multi_fixed_array_with_default_init() {
println(a)
assert a == [[10, 10, 10]!, [10, 10, 10]!, [10, 10, 10]!]!
}
struct Abc {
mut:
x i64
y i64
z i64
}
fn test_clone_of_same_elem_size_array() {
mut arr := []Abc{}
arr << Abc{1, 2, 3}
arr << Abc{2, 3, 4}
arr2 := arr.clone()
println(arr2)
assert arr2 == [Abc{1, 2, 3}, Abc{2, 3, 4}]
}