Forward-implement traits on smart pointers / make smart pointers more transparent


#1

Currently the support to use smart pointers in generic code is very limited because they do not forward the traits implemented by their content. Given one needs a [T], one might write a generic struct like

struct Container<T, V: AsRef<[T]>> {
    inner: V, _marker: PhantomData<T>
}

In such a case one could use a Vec<T> and a &[T] but not a Box<[T]> as Box does not implement AsRef.

My proposal would be to add

impl<T: ?Sized, V: AsRef<T> + ?Sized> AsRef<T> for Box<V> {
    #[inline]
    fn as_ref(&self) -> &T {
        unsafe {self.0.get()}.as_ref()
    }
}

to Box and equivalent implementations to Rc and Arc. Box should also forward AsMut.

Is this a sensible approach or are other things planned for smart pointers (like syntax sugar)? If so, which other traits beside AsRef would profit from such an approach?


#2

for now you can use Deref:

use std::ops::Deref;

fn test<T: Deref<Target=[u8]>>(t: T) {
    println!("{:?}", &*t);
}

fn main() {
    test(vec![5, 6, 7].into_boxed_slice());
    test(vec![5, 6, 7]);
    let a: &[u8] = &[5, 6, 7];
    test(a);
}

Playpen


#3

Just that Deref is not the “right” trait. Fixed-size arrays don’t and shouldn’t implement Deref.


#4

Good point… But at the same time AsRef isn’t the right trait for getting a reference to the inner value of a box. That would be Borrow imo, which actually exists. But it doesn’t exist on fixed-size arrays.

PlayPen