1

I'm trying to implement additional behaviour for a generic type if its type parameters meet particular trait bounds:

struct Foo<T> {
    data: T
}

impl<T> Drop for Foo<T> where T: Debug {
    fn drop(&mut self) {
        println!("{:?} has been deallocated", self.data);
    }
}

The idea being that Foo would implement Drop if T implements Debug, while still allowing Foo to be used for types T without Debug (which simply won't implement Drop). However, this results in a compiler error:

`Drop` impl requires `T: Debug` but the struct it is implemented for does not

Is there a way to achieve this behaviour (without splitting Foo into two separate types)?

This discussion suggests that this is not possible (or at least wasn't at the time):

Apparently this is only an issue for the Drop trait, for other traits it works just fine:

struct Foo<T> {
    data: T
}

trait MyDrop {
    fn drop(&mut self);
}

impl<T> MyDrop for Foo<T> where T: Debug {
    fn drop(&mut self) {
        println!("{:?} has been deallocated", self.data);
    }
}

So I guess my real question is: Why is conditional destructor implementation different from conditional implementation of other traits?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Henning Koehler
  • 2,456
  • 1
  • 16
  • 20
  • 1
    This discussion: https://users.rust-lang.org/t/drop-impl-requires-t-debug-but-the-struct-it-is-implemented-for-does-not/57763 suggests that this is not possible (or at least wasn't at the time). – Henning Koehler Aug 29 '22 at 01:32
  • 1
    This is still true. – Chayim Friedman Aug 29 '22 at 02:01
  • Any reason why this is prohibited, and is this something that will be addressed in the future? Conditional implementation of Foo methods seems to work fine (https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods). – Henning Koehler Aug 29 '22 at 02:07

1 Answers1

0

After reading and thinking about it some more, I believe the issue is that allowing conditional implementation for Drop would cause a conflict with the compiler-generated default implementation of Drop. That's similar to the way you cannot currently specialize an implementation, as discussed here.

However, once specialization becomes stable it might be possible to allow conditional implementation of Drop as well. Does that sound correct?

Henning Koehler
  • 2,456
  • 1
  • 16
  • 20