Skip to content

Cloning DSTs by bytes #2275

Open
Open
@kupiakos

Description

@kupiakos

Working with DSTs is much improved but is still challenging - especially owned DSTs. Being able to simply perform a bytewise clone into a Box would be very helpful. I propose it be derived via ByteClone.

While you can impl Clone for Box<LocalType> due to it being #[fundamental] and derive(ByteClone) probably should, there's no built-in trait for &self -> Box<Self>. So, this should also define a local ByteClone trait or something similar to generically define this.

Sample:

// In zerocopy:
pub trait ByteClone: KnownLayout + IntoBytes + FromBytes {
    fn byte_clone(&self) -> Self where Self: Sized;
    fn byte_clone_box(&self) -> Box<Self>;
}

// In local crate:
#[derive(ByteClone, IntoBytes, FromBytes, Immutable, KnownLayout)]
#[repr(C)]
struct Foo([u8]);

// Generates:

// This `for<'a>` trick is useful for macros to conditionally implement functionality
// on a concrete type dependent on a maybe-implemented trait.
impl Clone for Foo where for<'a> Foo: Sized {
    fn clone(&self) -> Self { self.byte_clone() }
}

impl ByteClone for Foo {
    fn byte_clone(&self) -> Self where for<'a> Self: Sized {
        Self::read_from_bytes(self.as_bytes()).unwrap()
    }
    
    fn byte_clone_box(&self) -> Box<Self> {
        Foo::read_box_from_bytes(self.as_bytes()).unwrap()
    }
}

impl Clone for Box<Foo> {
    fn clone(&self) -> Self {
        <Foo as ByteClone>::byte_clone_box(self.as_bytes())
    }
}
  • This requires Conversion between Box<T: Unalign> and Box<[u8]> #2258 and the ability to construct a Box from existing bytes for ?Sized.
  • Like in derive(ByteEq) #2274, this bytewise clone can also optimize better than field-wise derived clone for Sized + !Copy types.
  • Naming: fn byte_clone or fn clone_bytes? I like the readability of verb-noun, especially with clone_bytes_to_box instead of byte_clone_box. If clone_bytes is preferred, then should the trait be named CloneBytes? Then derive(ByteEq) #2274 (comment) should apply for consistency. ByteHash is already implemented.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions