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

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?

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

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

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

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.