rusttraitsdereferencedrop

Why can't I use the Deref trait inside Drop in Rust?


I implemented the Deref trait for the MyString struct which allows me to use an object of type MyString via *o or o.deref().

But when I implement the Drop trait for MyString then the already implemented Deref trait cannot be used inside the Drop trait. Why?

use std::ops::Deref;
use std::ops::DerefMut;

struct MyString {
    s: String,
}

impl Deref for MyString {
    type Target = String;

    fn deref(&self) -> &Self::Target {
        &self.s
    }
}

impl DerefMut for MyString {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.s
    }
}

impl Drop for MyString {
    fn drop(&mut self) {
        // println!("string dropped: {}", *self); // `MyString` doesn't implement `std::fmt::Display`
        // println!("string dropped: {}", self.deref()); // `main::MyString` doesn't implement `std::fmt::Display`

        println!("string dropped: {}", self.s); // works
    }
}
let s1 = MyString {
    s: "abc".to_string(),
};
println!("s1: {}", *s1);
println!("s1: {}", s1.deref());

Solution

  • Because self in deref is a reference, you need to dereference twice:

    println!("string dropped: {}", **self);
    println!("string dropped: {}", self.deref().deref());