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

use std::ops::Deref;
use std::fmt;
use std::fmt::{Formatter, Debug};

fn main() {
    let value_box = Box::new(12);
    let value = *value_box;
    println!("{}", value);
    println!("value_box {:?}", value_box);

    let value_box = MyBox::new(12);
    let value = *value_box;
    println!("{}", value);
    println!("value_box {}", value_box);
    println!("value_box {:?}", value_box);
}

#[derive(Debug)]
struct MyBox<T>(T);

impl<T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

impl<T> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T: Debug> fmt::Display for MyBox<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl<T: Debug> Drop for MyBox<T> {
    fn drop(&mut self) {
        println!("MyBox dropped {:?}", self);
    }
}

The compilation error is as follows:

error[E0367]: `Drop` impl requires `T: Debug` but the struct it is implemented for does not
  --> src/main.rs:41:9
   |
41 | impl<T: Debug> Drop for MyBox<T> {
   |         ^^^^^
   |
note: the implementor must specify the same requirement
  --> src/main.rs:19:1
   |
19 | struct MyBox<T>(T);
   | ^^^^^^^^^^^^^^^^^^^

Compilation error, I don’t know how to solve it. According to the official tutorial, I want to add a string of logs to be printed when the log is destroyed.

rust playground link:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=289d9e353283ec3463d77ddb9a0bb297

Due to the limitation of the (current) type system, you can't conditionally implement the Drop trait. To add T: Debug bound to the impl Drop, the struct declaration should also have same bound.

#[derive(Debug)]
struct MyBox<T: Debug>(T);

impl<T: Debug> Drop for MyBox<T> {...}
2 Likes

Thank you very much, it has been resolved.
Paste the complete code:

use std::ops::Deref;
use std::fmt;
use std::fmt::{Formatter, Debug};

fn main() {
    let value_box = Box::new(12);
    let value = *value_box;
    println!("{}", value);
    println!("value_box {:?}", value_box);

    let value_box = MyBox::new(12);
    let value = *value_box;
    println!("{}", value);
    println!("value_box {}", value_box);
    println!("value_box {:?}", value_box);
}

#[derive(Debug)]
struct MyBox<T: Debug>(T);

impl<T: Debug> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

impl<T: Debug> Deref for MyBox<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.0
    }
}

impl<T: Debug> fmt::Display for MyBox<T> {
    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl<T: Debug> Drop for MyBox<T> {
    fn drop(&mut self) {
        println!("MyBox dropped {:?}", self);
    }
}