Skip to content

Document that #[derive(IntoBytes)] only supports unsized types which are repr(packed) #1566

Closed
@njsmith

Description

@njsmith

Update (authored by @joshlf)

See #1566 (comment).

This issue tracks improving the documentation on either IntoBytes or the re-export of zerocopy_derive::IntoBytes to document that #[derive(IntoBytes)] does not support unsized types unless those types are also repr(packed).

Original issue text

Original title: Can't #[derive(IntoBytes)] on a slice DST?

I'm experimenting with the current main branch (1ff83c4) and its support for slice DSTs. I wrote:

// This is a dynamically sized type
#[derive(Debug, FromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(C)]
pub struct StatsReport {
    written: U64,
    values: [U64],
}

As far as I can tell from the docs, this should be supported in this branch?

But it errors out with:

error[E0277]: the size for values of type `[U64<zerocopy::BigEndian>]` cannot be known at compilation time
  --> [...]/stats.rs:21:12
   |
21 | pub struct StatsReport {
   |            ^^^^^^^^^^^ doesn't have a size known at compile-time
   |
   = help: within `StatsReport`, the trait `Sized` is not implemented for `[U64<zerocopy::BigEndian>]`, which is required by `StatsReport: Sized`
note: required because it appears within the type `StatsReport`
  --> [...]/stats.rs:21:12
   |
21 | pub struct StatsReport {
   |            ^^^^^^^^^^^
note: required by a bound in `std::mem::size_of`
  --> /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/mem/mod.rs:312:1

error[E0277]: the size for values of type `[U64<zerocopy::BigEndian>]` cannot be known at compilation time
  --> [...]/stats.rs:23:13
   |
23 |     values: [U64],
   |             ^^^^^ doesn't have a size known at compile-time
   |
   = help: the trait `Sized` is not implemented for `[U64<zerocopy::BigEndian>]`
note: required by a bound in `std::mem::size_of`
  --> /rustc/25ef9e3d85d934b27d9dada2f9dd52b1dc63bb04/library/core/src/mem/mod.rs:312:1

For more information about this error, try `rustc --explain E0277`.

The error message is annoyingly uncommunicative about what's going on, but the problem seems to be the #[derive(IntoBytes)], where cargo expand shows that zerocopy is generating this code:

    unsafe impl ::zerocopy::IntoBytes for StatsReport
    where
        U64: ::zerocopy::IntoBytes,
        [U64]: ::zerocopy::IntoBytes,
        ::zerocopy::macro_util::HasPadding<
            StatsReport,
            {
                ::zerocopy::macro_util::core_reexport::mem::size_of::<StatsReport>()
                    > 0 + ::zerocopy::macro_util::core_reexport::mem::size_of::<U64>()
                        + ::zerocopy::macro_util::core_reexport::mem::size_of::<[U64]>()
            },
        >: ::zerocopy::macro_util::ShouldBe<false>,

which yeah, doesn't seem like that could work.

I figure this might be any of:

  • a bug
  • not expected to work, docs should be clarified
  • chill out dude, this is unreleased and unfinished, we'll get there

...But figured I'd check.

Metadata

Metadata

Assignees

No one assigned

    Labels

    blocking-next-releaseThis issue should be resolved before we release on crates.io

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions