Is there a good reason not to automatically implement AsRef<T> for Deref<Target=T>?

Something like:

impl<T> AsRef<T> for dyn Deref<Target=T>
where
    T: ?Sized
{
    fn as_ref(&self) -> &T {
        self.deref()
    }
}

dyn Deref trait objects seem weird. Definitely uncommon, not too useful. I don't see the point in implementing AsRef for them. If you're instead referring to a blanket impl like

impl<S, T> AsRef<T> for S
where
    T: ?Sized
    S: ?Sized + Deref<Target=T> 
{
    fn as_ref(&self) -> &T {
        self.deref()
    }
}

then: introduction of such an impl would be a breaking change AFAICT, and probably also in conclict with other existing blanket implementations, as it would - I think - imply AsRef<T> for &T generically, which is not a thing either. (Because of overlap with the existing implementation of AsRef for &T.)

The implementation for dyn Deref<Target=T> specifically is also backwards incompatible, because you can implement AsRef<LocalType> for dyn Deref<Target=LocalType>.

(If you're thinking "but neither the type nor the trait is local", the actual orphan rules are more nuanced.)

2 Likes