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.