When `impl Deref` is OK?

As per https://doc.rust-lang.org/std/ops/trait.Deref.html

"Implementing Deref for smart pointers makes accessing the data behind them convenient, which is why they implement Deref. On the other hand, the rules regarding Deref and DerefMut were designed specifically to accommodate smart pointers. Because of this, Deref should only be implemented for smart pointers to avoid confusion. "

But what is the definition of a “smart pointer”? In a lot of cases it’s no clear.

Is a type-safety newtype, for the inner type? If not then, why is AssertUnwindSafe does Deref? Or guards likeMutexGuard`?

One way or another, I think the documentation should elaborate more on that.

2 Likes

The point here is not that the type must be a pointer specifically, but rather that it should be a holder of a single type. There is another trick, which I have used, which is discouraged (except in private) which is to emulate an “is a” relationship (i.e. inheritance) by making the child type deref to the parent type. This can save a lot of code duplication and thus is tempting, but ends up leading to confusing error messages and error cases.

Not sure if this helps, and I have no knowledge of what was really intended by those writing that documentation.

This is specifically the scenario that is always tempting. And then … aren’t guards implementing Deref or even Vec or String doing the exact same thing?

1 Like

Vec and String contains a pointer to the slice, and MutexGuard contains a &mut of the guarded value.