error[E0367]: `Drop` impl requires `T: std::fmt::Display` but the struct it is implemented for does not

Drop トレイトの実装を、ジェネリクス型の特定の型パラメタに対して特殊化しようとした。

原因

、GitHub 上の改善依頼を見ると、このエラーは歴史的経緯によるものらしい。

サンプル

以下では、ジェネリクス型 MyStruct<T> にトレイト Drop を、型パラメタ TDisplay を実装する場合にだけ特殊化して実装しようとしている。


use std::fmt::Display;

fn main() {
    let _ = MyStruct("test");
}

struct MyStruct<T>(T);

impl<T> Drop for MyStruct<T>
where
    T: Display
{
    fn drop(&mut self) {
        println!("`{}` is droped.", self.0)
    }
}

error[E0367]: `Drop` impl requires `T: std::fmt::Display` but the struct it is implemented for does not
  --> src\main.rs:11:8
   |
11 |     T: Display
   |        ^^^^^^^
   |
note: the implementor must specify the same requirement
  --> src\main.rs:7:1
   |
7  | struct MyStruct<T>(T);
   | ^^^^^^^^^^^^^^^^^^

回避策

ジェネリクス型の型パラメタと実装時の型パラメタの境界条件を同じにすれば、何も制限していないため特殊化とはならない。そのため、Drop の実装時と境界条件を合わせたラッパー型を用意すればよい。


以下では、型 MyStruct<T> のラッパー型 MyStructWrapper<T> の境界条件が、Drop の実装時の境界条件と同じで、T: Display になっている。


use std::fmt::Display;

fn main() {
    let _ = MyStructWrapper(MyStruct("test"));
}

struct MyStruct<T>(T);

struct MyStructWrapper<T>(MyStruct<T>)
where
    T: Display;

impl<T> Drop for MyStructWrapper<T>
where
    T: Display,
{
    fn drop(&mut self) {
        println!("`{}` is droped.", self.0 .0)
    }
}