Implementing over a generic-element AsRef

I'm sure this has been discussed elsewhere, but I can't find anything. How would you make this work?

pub trait IndexedDict { 
   type Output;
    unsafe fn get_unchecked(&self, index: usize) -> Self::Output;
}


impl<T, S: AsRef<[T]>> IndexedDict for S {
    type Output = T;
    unsafe fn get_unchecked(&self, index: usize) -> Self::Output {
        *self.as_ref().get_unchecked(index)
    }
}

playground

You can't. The type S might implement both AsRef<[u8]> and AsRef<[String]>, but if that happens, then your code would implement IndexedDict twice for S. You can only implement a trait once, so that's not allowed.

Either replace AsRef with another trait that also uses an associated type (e.g. Deref), or move Output to a generic paramter.

Ok, but how would it work with Deref?

use core::ops::Deref;

pub trait IndexedDict {
   type Output;
    unsafe fn get_unchecked(&self, index: usize) -> Self::Output;
}

impl<T: Copy, S: Deref<Target = [T]>> IndexedDict for S {
    type Output = T;

    unsafe fn get_unchecked(&self, index: usize) -> Self::Output {
        *self.deref().get_unchecked(index)
    }
}
1 Like

Thanks! I was trying &[T] as a target and clearly that was wrong.

deref() returns &Target, so if the return type is &[T], then naturally Target = [T], not &[T].

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.