How to implement Index<Range<usize>> for a custom slice type with additional data?

This is a follow up from this topic.

Now I don't just want to "strong typedef" vectors and slices, but I want to have a special slice type that carries extra information not present in the vector type. Example:

struct Vector(Vec<u8>);

struct Slice<'a> {
    slice: &'a [u8],
    property: bool,
}

impl Index<Range<usize>> for Vector {
    type Output = Slice<'a>; // Where do I get this lifetime from?
    // Simply adding impl<'a> does not work,
    // and GATs would require a change in the definition of the `std::ops::Index` trait.

    fn index(&self, index: Range<usize>) -> &Self::Output {
        let result = Slice { slice: self.0.index(index), property: true };
        todo!("How to return a reference here?")
    }
}

impl<'a> Index<Range<usize>> for Slice<'a> {
    type Output = Self;

    fn index(&self, index: Range<usize>) -> &Self::Output {
        let result = Self { slice: self.slice.index(index), property: self.property };
        todo!("How to return a reference here?")
    }
}

Note that the property is local to the Slice and not global to the Vector, so e.g. two instances of Slice with equivalent slice may have different property.

I cannot just create a new Slice and return a reference, because this would result in use-after-free.
Unfortunately, ref-cast does not seem to support slice types with extra data. Also, slice-dst does not seem to support what I need, although I am not sure about that.

Is there a trick or crate to implement Index<Range<usize>> for a slice and vector type-pair like the one I have here?

You can't, use a normal method instead of Index.

1 Like

Thanks.

Are there any plans to make this possible in the future?

It's hard to say, because it would be difficult to change the Index trait due to back compat concerns. And supporting this would require changing it, because returning a reference is too restrictive to allow this to work. I wouldn't bet on it happening anytime soon.

Hm okay. I understand the concerns for backwards compatibility... I still hope it will happen one day :slight_smile:

It would allow for more complex sets of types to use syntax simplifications, like it is possible for any type in C++.

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.