Reputation: 702
I have some questions regarding the relationship of drop/copy traits and ownership in Rust. The most important question: How do I know that a type is a type where the ownership rules apply? My best guess it is related to the lack of a copy trait. But I have never seen this stated explicity. Is this true? So my general question: If I have an assignment
let s=...
let t=s
how do I know if s is invalid afterwards? Is it solely dependent on the absence of a copy-trait?
Further, in textbooks ownership is always explained via using a type with the drop trait (e.g. vec/String). This gives the impression - which I think is false - that move-semantics is always tied to the presence of a drop trait. But I wonder if it is necessary for a type to have a drop trait in order to follow the ownership rules? E.g. isn't the drop trait just some cleanup code which is run when the variable goes out of scope?
One last note: The JoinHandle type lacks a drop trait - yet it is called an owned type. So I guess this points to the fact that a drop trait is not necessary for a type to be called an owned type. But is it sufficient? E.g. are all types with a drop trait owned types?
EDIT:
No, I thought that the copy trait is the indicator for move/ownership semantics. But after reading the following passage I am confused: (From chapter 16 of the Rust programming language) "The Send marker trait indicates that ownership of the type implementing the Send can be transferred between threads" and further below "Almost all primitive types are Send".
Maybe I misunderstand something but to me this seems contradictory: A primitve type (such as i32) is Copy and therefore not an owned type. Yet the line talks about ownership transfer. How can you transfer ownership with a type that is copy?
Upvotes: 0
Views: 268
Reputation: 71380
If I have an assignment, how do I know if s is invalid afterwards? Is it solely dependent on the absence of a copy-trait?
Yes. A value that does not implement the Copy
trait is moved; a value that does implement it is copied.
But I wonder if it is necessary for a type to have a drop trait in order to follow the ownership rules?
No, it is not. I guess ownership is usually explained in terms of Drop
because it is easier to explain why it is problematic for types that implement Drop
to be used after being moved (causing a use-after-free or double drop). But there are also use cases for types that do not implement Drop
yet their represent a resource of some kind that cannot be duplicated.
The JoinHandle type lacks a drop trait - yet it is called an owned type. So I guess this points to the fact that a drop trait is not necessary for a type to be called an owned type.
This is actually not a great example, because while JoinHandle
(assuming you refer to std::thread::JoinHandle
) does not implement Drop
itself, it has a drop glue. This is the name for the code that the compiler automatically generates to drop the fields of a type. But as I said, in general you are correct. Types may not implement Drop
yet have ownership semantics.
But is it sufficient? E.g. are all types with a drop trait owned types?
Yes, because implementing Drop
for a type disallows implementing Copy
for it.
About your edit: the book is not accurate. A more accurate statement is to say: "The Send
marker trait indicates that ownership of the type implementing the Send
or their copies can be transferred between threads". Alternatively, one can argue that even for Copy
types, you (semantically) make a copy of them then pass the ownership of the copy to someone else (because you're discarding it). Either way, this does not change what I said above.
Upvotes: 3