M
Modular•12mo ago
vmois

Owned convention does not destroy variable after transferring ownership

Hello everybody! I am working on a project that has a small exercises to learn Mojo. Currently, I am working on value ownership section and was playing with a code below.
# TASK
# Make file compile with no errors

# I AM NOT DONE

fn take_ptr(owned array: Pointer[Int]):
array.store(2, 23)


fn main():
# this line just allocates pointer for 3 integers
var array = Pointer[Int].alloc(3)

array.store(0, 1)
array.store(1, 2)

# this function call does not need any changes
take_ptr(array^)

array.store(2, 2)
print(array[2])
# TASK
# Make file compile with no errors

# I AM NOT DONE

fn take_ptr(owned array: Pointer[Int]):
array.store(2, 23)


fn main():
# this line just allocates pointer for 3 integers
var array = Pointer[Int].alloc(3)

array.store(0, 1)
array.store(1, 2)

# this function call does not need any changes
take_ptr(array^)

array.store(2, 2)
print(array[2])
The issue I have is that this code compiles but to my understanding of owned and ownership operator it shouldn't. If you take equivalent code for string, it has an error "a is not initialized":
fn take_text(owned text: String):
text += "🔥"
return text


fn main():
var a: String = "mojo"

take_text(a^)
print(a)
fn take_text(owned text: String):
text += "🔥"
return text


fn main():
var a: String = "mojo"

take_text(a^)
print(a)
For equivalent integer code:
fn take_value(owned x: Int):
x += 2


fn main():
var x: Int = 1
take_value(x^)
print(x)
fn take_value(owned x: Int):
x += 2


fn main():
var x: Int = 1
take_value(x^)
print(x)
It throws no error, and value of x is 1. Can someone please explain if this behaviour is correct or am I missing something? Thank you.
4 Replies
vmois
vmoisOP•12mo ago
I filled a bug report on Mojo repository - https://github.com/modularml/mojo/issues/1604. The behaviour seems unusual to me, so either we can include more clarification in the docs or indeed it is a bug.
GitHub
Issues · modularml/mojo
The Mojo Programming Language. Contribute to modularml/mojo development by creating an account on GitHub.
Chris Lattner
Chris Lattner•12mo ago
There are a few bugs in this area, and hte model got a bit simplified (e.g. take semantics is removed from the ^) operator. The next update will be a big one in this department
vmois
vmoisOP•12mo ago
Thank you for the answer. I will wait for the next update and as soon as it is published I will re-check this behaviour. Very excited to finilize exercises for value ownership and semantics. Just need them to get a bit more stable.
Arthur Evans
Arthur Evans•12mo ago
A quick answer on the current state of affairs which might shed a little light here: the current Pointer is unsafe. The owned convention should force a copy of the value, but copying a Pointer doesn't copy the memory that it points to. I'm not positive, but I suspect you're seeing the same thing in the Pointer case and the Int case--the ^ operator is basically ignored because an Integer is just a value in a register, and we don't need to destruct it. (And a pointer is basically just an integer.) In the case of the integer, you can see that the value was copied--the x in main and the x in take_value() end up with different values. The string example does what you'd expect it do with any non-trivial type: the value is destructed after you pass it in to take_text(). You'd see the same result if you used a DynamicVector in your first example instead of a raw Pointer.
Want results from more Discord servers?
Add your server