Edition idea: Should any type that has drop glue be considered to impl Drop?

Can you elaborate on this? Without specialization or negative trait bounds, a 'reliable Drop bound' would only allow you to require that a type have drop glue. That is, T: ReliableDrop would hold for String and MyWrapper(String), but not for u8.

Surprisingly, there is actually a (quite obscure) use for Drop bounds currently:

trait PreventExplicitDropImpl {}
impl<T: Drop> PreventExplicitDropImpl for T {}

struct Foo;
impl PreventExplicitDropImpl for Foo {}

impl Drop for Foo {
    fn drop(&mut self) {}
}

This code causes a compile error if there is an explicit Drop impl for Foo, but does not error if Foo just has drop glue.

This is actually used by the pin-project crate, which needs to be able to prevent users from writing a manual Drop impl (pin-project does not need to prevent drop glue).

Thus, changing the behavior of Drop would be a breaking change.

If you want to be able to express std::mem::needs_drop<T> via the trait system (with all the limitations that currently entails), it's actually possible on Nightly via const-generics (playgroud):

#![feature(const_generics)]
#![feature(const_evaluatable_checked)]

trait NeedsDrop {}

impl<T> NeedsDrop for T where Bool<{std::mem::needs_drop::<T>()}>: True {}

struct Bool<const B: bool>;
trait True {}
impl True for Bool<true> {}

fn assert_needs_drop<T: NeedsDrop>() where Bool<{std::mem::needs_drop::<T>()}>: True {}

struct WithDropGlue {
    val: String
}

fn main() {
    assert_needs_drop::<String>();
    assert_needs_drop::<WithDropGlue>();
    assert_needs_drop::<u8>();
}

It currently requires a duplicated where clause on assert_needs_drop, but I believe that should be addressed in coming changes to const-generics.

8 Likes