Description
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.