Skip to content

Support generic parameters when deriving AsBytes on a #[repr(transparent)] type #9

@joshlf

Description

@joshlf

Migrated from https://fxbug.dev/84475

Originally reported by @Kestrer

Hi, I'm not quite sure how to open an issue with Zerocopy directly so I hope I put this in the right place.

I'm the maintainer of the bounded-integer crate (https://docs.rs/bounded-integer) and I would like to support implementing the Zerocopy traits on the bounded integers. My code looks something like this:

type Inner = u8;

#[derive(Unaligned, AsBytes)]
#[repr(transparent)]
pub struct Bounded<const MIN: Inner, const MAX: Inner>(Inner);

However zerocopy complains because it doesn't support generic parameters.

Comment by @cmyr

I've also just run into this, and I'd be happy to prepare a patch if that would be welcome (and if I can remember how gerrit works).

I've taken a quick skim through the current impl, and stared into space for a few minutes, and it isn't obvious to me why this constraint exists, currently. I trust there is a reason (given that the limitation does not exist for FromBytes) but it isn't obvious to me what it is, so any useful information here would be welcome. :)

Comment by @joshlf

Hi folks, sorry for the delay in responding to this.

Generic parameters are supported for Unaligned - try deriving that trait on its own without AsBytes.

The reason that AsBytes doesn't support generic parameters is that I haven't figured out a way to ensure that the resulting type has no padding, which is a requirement for AsBytes. In particular, consider the following type:

#[repr(C)]
struct Foo<T, U> {
    t: T,
    u: U,
}

In order for Foo<T, U> to be AsBytes, there can't be any padding. That, however, depends on both the sizes and alignments of T and U. I haven't figured out how to write an impl bound that expresses the right requirements.

Take a look at the implementation of the AsBytes derive for how we do this when there are no generic parameters - we use const code to compare the size of the type to the sum of the sizes of its fields. That approach doesn't translate since const generics aren't powerful enough yet to just use the same code in an impl bound. We'd need another approach.

Comment by @joshlf

Update: Some of the other developers realized that we can probably support your specific use case more easily since your type is #[repr(transparent)], and thus we don't need to worry about any layout computation - we just need to bound Inner: AsBytes. I'm changing this issue to track that more narrow goal.

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