About ownership


Why doesn't the compiler issue an error at Line 15 while I am trying to assign it's field with a new value ? It did throw a message at Line 16 saying p was moved at Line 14 already.


This section in the documentation is describing what is happening What is Ownership? - The Rust Programming Language

Also a small hint. You can post code here without using screenshots by writing the code within these blocks

Code goes here


In this section, The Book also states that :

If we tried to use s after the call to takes_ownership, Rust would throw a compile time error.

I wander that why the compiler complains at Line 16 , not Line 15. Both use the moved variable p. I reassign p's field x at Line 15 and the compiler doesn't give a warning or an error. For the user's perspective, Line 15 is useless if so. My question is: what does the compiler do when it comes to Line 15 ?

The line 15 is a partial initialization. (Failing to find a doc link.) It isn't used very often.

I think you can use the following mental model: moving is essentially memcpy-ing the struct to the called function stack. (usually it's optimized out, but initially it's there) Memory region of old p is still there on stack, but is marked as "moved", which makes it unreadable, but it does not forbid you from writing into that memory. Same story applies to this example:

let mut p: Point;
// works
p.x = 5;
// compilation error
println!("{}", p.x)

The only difference is that memory region of p marked not as "moved", but as "uninitialized". Although I agree that your example is strange and ideally Rust should produce error for line 15 as well. (of course if I am not missing some obscure cases where such behaviour will be useful)

I have no idea what the use cases are; but IIRC if you assign all of the fields in this manner, Rust will consider the object to be fully initialized.

Just watch out for the terrifying soundness hole. (surprise, a feature that almost nobody uses has bugs!)


Nope, it does not work like this unfortunately. It could be a nice (but arguably rarely needed) feature if Rust could've tracked partial initialization and detect if type became fully initialized.

1 Like

This is issue #21232.