Skip to content

Support slicing a KnownLayout type #1290

@joshlf

Description

@joshlf

Progress


Given a &[T], Rust supports creating a new &[T] referring to a subset of the original referent, and also supports splitting into two non-overlapping &[T]s that, together, cover the original referent. To my knowledge, this is not supported for slice DSTs.

We could add APIs for these slicing operations to KnownLayout<PointerMetadata = usize>.

One use case for this design would be to support packet formats with explicit length fields - it would be a possibly lighter-weight way of supporting #1289 without requiring solving the general problem described in that issue.


Suggestion thanks to @kupiakos: Currently the API looks like this:

pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
    fn split_at(&self, l_len: usize) -> Option<(&Self, &[Self::Elem])>
       where Self: Immutable { ... }

    fn split_at_mut(
        &mut self,
        l_len: usize,
    ) -> Option<(&mut Self, &mut [Self::Elem])> { ... }
}

We want to make two changes:

  • Support cases in which there is guaranteed to be no padding (thanks to IntoBytes)
  • Support shared references when Self: !Immutable, adding padding overlap as an error condition

We can support these uniformly like so:

pub unsafe trait SplitAt: KnownLayout<PointerMetadata = usize> {
    fn split_at(&self, l_len: usize) -> Result<(&Self, &[Self::Elem]), SplitAtError<&'_ Self>> { ... }

    fn split_at_mut(
        &mut self,
        l_len: usize,
    ) -> Result<(&mut Self, &mut [Self::Elem]), SplitAtError<&'_ mut Self>> { ... }
}

pub struct OutOfBoundsError;

pub struct PaddingOverlapError;

pub enum SplitAtError<Src, PaddingOverlap = PaddingOverlapError> {
    OutOfBounds(OutOfBoundsError),
    PaddingOverlap(PaddingOverlap),
}

We can then provide methods which convert SplitAtError<_, PaddingOverlapError> to SplitAtError<_, !> with certain bounds:

  • SplitAtError<&T, PaddingOverlapError> -> SplitAtError<&T, !> where either:
    • T: Immutable
    • T: IntoBytes
  • SplitAtError<&mut T, PaddingOverlapError> -> SplitAtError<&mut T, !> where T: IntoBytes

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions