In fact, mem::drop will accept any value, whether it implements Drop or not.
The author of the article is definitely quite confused about Drop vs mem::drop. mem::drop is not an implementation of Drop.
> In fact, mem::drop will accept any value, whether it implements Drop or not.
This doesn't mean that it isn't defined in terms of Drop, because there is no such thing as !Drop in Rust. Even things that are Copy are implicitly Drop, it's just that the copy is dropped instead of the value.
While that mental model could make sense in an abstract way, it's not literally true. Copy types are forbidden to implement Drop.
fn takes_drop<T: Drop>(t: T) {
todo!()
}
fn main() {
takes_drop(5i32);
}
gives error[E0277]: the trait bound `i32: Drop` is not satisfied
--> src/main.rs:6:20
|
6 | takes_drop(5i32);
| ---------- ^^^^ the trait `Drop` is not implemented for `i32`
| |
| required by a bound introduced by this call
|
note: required by a bound in `takes_drop`
--> src/main.rs:1:22
|
1 | fn takes_drop<T: Drop>(t: T) {
| ^^^^ required by this bound in `takes_drop`Would it be more accurate to say that Rust guarantees the droppability of owned values? I know there's a guarantee that &'static items never have their underlying value dropped, but that works because you can never actually hold the static value itself, only its reference.
Everything isn’t implicitly Drop. Drop is an explicit cleanup mechanism that types can opt into.
If it helps you to think of it conceptually as everything having an implicit no-op Drop, then I guess that’s fine, but that’s not what is happening.
There is an automatic Drop “glue code” for types that contain types that implement Drop, so that those will get called, of course. But `i32` does not have Drop, at all.
> Even things that are Copy are implicitly Drop, it's just that the copy is dropped instead of the value.
You cannot implement Drop on a Copy type, so Drop literally never gets called on Copy types. You can’t put non-Copy types inside a Copy type, so there isn’t even Drop glue code. And no, it isn’t implicitly Drop at all! And it has nothing to do with a copy being dropped instead of the original value. Drop isn’t a universal trait.
I also seem to remember in the early post-1.0 days that whether a type implemented Drop or not would significantly impact lifetime analysis, requiring some occasionally obtuse workarounds. Rust lifetime analysis accepts many more correct solutions these days, and it has been awhile since I wrote a lot of Rust code, so I don’t recall how it is these days.
I understand that types that don't implement Drop do not literally have an implicit `Drop` trait implemented for them by the compiler.
What I meant is that there is no "undroppable" type in Rust: the best you can do is make the type panic in a custom Drop implementation, but any function that takes ownership of a value is effectively described as forwarding, dropping, or forgetting that value based on the lifetime/type of its return. In other words, `mem::forget` can only be defined in terms of Drop (or default drop behavior for a type) in terms of ownership semantics, because its signature admits no other possibilities.