Lifecycle doc clarification

I was reading https://docs.modular.com/mojo/manual/lifecycle/life#move-constructor, the following struc is given as an example:
struct HeapArray:
var data: Pointer[Int]
var size: Int

fn __init__(inout self, size: Int, val: Int):
self.size = size
self.data = Pointer[Int].alloc(self.size)
for i in range(self.size):
self.data.store(i, val)

fn __copyinit__(inout self, existing: Self):
# Deep-copy the existing value
self.size = existing.size
self.data = Pointer[Int].alloc(self.size)
for i in range(self.size):
self.data.store(i, existing.data.load(i))

fn __moveinit__(inout self, owned existing: Self):
print("move")
# Shallow copy the existing value
self.size = existing.size
self.data = existing.data
# Then the lifetime of "existing" ends here, but
# Mojo does NOT call its destructor

fn __del__(owned self):
self.data.free()
struct HeapArray:
var data: Pointer[Int]
var size: Int

fn __init__(inout self, size: Int, val: Int):
self.size = size
self.data = Pointer[Int].alloc(self.size)
for i in range(self.size):
self.data.store(i, val)

fn __copyinit__(inout self, existing: Self):
# Deep-copy the existing value
self.size = existing.size
self.data = Pointer[Int].alloc(self.size)
for i in range(self.size):
self.data.store(i, existing.data.load(i))

fn __moveinit__(inout self, owned existing: Self):
print("move")
# Shallow copy the existing value
self.size = existing.size
self.data = existing.data
# Then the lifetime of "existing" ends here, but
# Mojo does NOT call its destructor

fn __del__(owned self):
self.data.free()
what does Then the lifetime of "existing" ends here, but Mojo does NOT call its destructor mean? I understand that existing.data must not be free but what about existing.size? is it freed even though the destructor is not called? in theory a copy was made by doing self.size = existing.size
Life of a value | Modular Docs
An explanation of when and how Mojo creates values.
4 Replies
Jack Clayton
Jack Clayton8mo ago
This means that the exisiting HeapArray can no longer be used when the move operator is used: ^, but it also shouldn't free the data because now self (the object it's being moved to) owns the data. Now the last use of self will free the data
artemiogr97
artemiogr97OP8mo ago
But lines self.size = existing.size and self.data = existing.data are creating copies, are they not ? Shouldn't the move operator also be used in those lines?
Michael K
Michael K8mo ago
Int and Pointer are register passable and "trivial". So they can only be copied. For simple things in register copying is more efficient than moving.
Jack Clayton
Jack Clayton8mo ago
Yeah exactly what @Michael K wrote, the expensive thing to copy is what's allocated by self.data, and that's not being copied just the Pointer to it. Passing 128bit of data through registers is trivial.
Want results from more Discord servers?
Add your server