I have a question of understanding regarding drop glue and types which are
As far as I know types which are
Copy don't get any drop glue from the compiler. Then how are they cleaned up?
Are they perhaps otherwise implicitly cleaned up by the stack? I've currently no idea.
I'm not really sure what you mean by "cleaned up". Memory on the stack will just be reused. The next time that memory location is used as part of a stack value, the old memory will simply be overwritten with a new value.
Copy types definitionally don't need additional logic to clean up after them, since they can't implement
Drop and can't contain other types that aren't
I'm sorry, I'm trying to make my statement more precise:
As I understand it, the compiler inserts drop glue in the program for certain types in order to make the used memory available again for other purposes but I've read (eg here) that the compiler won't add any drop glue for types which are
Copy. So my question is: Which mechanism(s) ensures that the used memory of such types, which are
Copy, gets freed again?
The drop glue is responsible for calling the
Drop impls to free resources held by the value. The memory containing the value itself is not freed up by the drop glue. As a
Copy type can't have any associated resources by the virtue of not being able to implement
Drop and by being freely copyable, there is no drop glue to run. If the value is held on the stack, the memory is reused either when the function returns or in some cases if the value becomes dead and the compiler reused the place on the stack for another value. If the value is on the heap, the drop glue of the value owning the heap location (eg
Vec) is responsible for freeing the memory, not the value that is stored on the heap itself.
The compiler will always make the memory free for other purposes, regardless of whether the type is
Copy or not. Some types need to do more than just have their memory freed when they go out of scope - for this purpose, Rust has the
Drop::drop trait method, which you implement to have the compiler run code when your type goes out of scope, just before the compiler inserts code that frees the memory for your instance.
"Drop glue" is the code the compiler inserts to run
Drop::drop methods when you let a value go out of scope. This allows for (e.g.) a
std::fs::File to close the file it has open just before you free up the memory that tells the
std::fs::File code which file you have open.
@bjorn3 and @farnz
For my understanding what you say about drop glue is not correct according to std::ops::Drop
My current understanding about drop glue is that the compiler might even add drop glue for a type that is not
Well, a simple example is that
String does not implement
Drop itself, but it definitely has drop glue for its
Vec field. But a type can only implement
Copy if all of its fields do as well, so there can't be any drop glue at all.
Drop glue exists to call drop on the fields of a type if the field types implement
If none of the fields implement
Drop, there's no need for drop glue code to be generated.
Omg... I completely misunderstood something while reading std::ops::Drop... sorry folks! Thank you very much for your help!!!
Of course, to be more precise, fields that don't implement
Drop but merely have
Drop glue are also causing their parent type to have
Drop glue. I. e. it's a recursively defined thing, considering fields, and fields of fields, and fields of fields of fields, and so on.
(Also as a special case, types like
ManuallyDrop never have drop glue.)
MaybeUninit is a
union, so isn't exactly a special case -- the rule is
unions cannot contain fields that may need dropping
note: a type is guaranteed not to need dropping when it implements
Copy, or when it is the special
MaybeUninit is taking advantage of
ManuallyDrop's special case to work, rather than being special itself:
Alright. In my mind I would have considered that an implementation detail
It's never clear to me what should or shouldn't be considered that.
After all, rustdoc thinks it's important that it's a union https://doc.rust-lang.org/nightly/std/mem/index.html#unions
So I go with "you could write your own
MaybeUninit, but you can't write your own
Of course, I fully agree with this. On the other hand, I think it's also useful that one can understand
MaybeUninit without considering (or even knowing) that it's implemented using a
Regarding the documentation distinguishing
union, AFAIR that's a point that has existing discussions as to whether that's something rustdoc should maybe not call out for opaque types.
I get it, abstraction boundary and all, but I need to look behind the curtain often enough I get annoyed when rustdoc omits information... much less intentionally obscures it.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.