* Add support for deriving Zeroable for fieldful enums if:
1. the enum is repr(Int), repr(C), or repr(C, Int),
2. the enum has a variant with discriminant 0,
3. and all fields of the variant with discriminant 0 are Zeroable.
* Allow using derive(Zeroable) with explicit bounds. Update documentation and doctests.
* doc update
* doc update
* remove unused
* Factor out get_zero_variant helper function.
* Use i128 to track disciminants instead of i64.
* Add doc-comment for `get_fields`
Co-authored-by: Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>
* Update derive/src/traits.rs
Co-authored-by: Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>
---------
Co-authored-by: Daniel Henry-Mantilla <daniel.henry.mantilla@gmail.com>
* Change #![allow(clippy::missing_docs_in_private_items)] to #[allow(clippy::missing_docs_in_private_items)], also rustfmt went wild
* fix for 1.34 building.
* clippy be quiet
* derive changelog.
* chore: Release bytemuck_derive version 1.7.0
* Change #![allow(clippy::missing_docs_in_private_items)] to #[allow(clippy::missing_docs_in_private_items)], also rustfmt went wild
* fix for 1.34 building.
* clippy be quiet
Note that the ergonomics are still not great, since `NoUninit` is also required to use `derive(ByteEq, ByteHash)`, and `derive(NoUninit)` doesn't support generics,
but that *explicitly* doesn't support generics, instead of silently ignoring generics like `derive(ByteEq, ByteHash)` used to, so this is strictly an improvement.
* simplify `ToTokens` impl for `Representation`
Instead of collecting the representation and modifier into `Option`s
and determining whether a comma is needed manually, we can use the
`Puncutuated` struct which handles commas automatically.
This will also make emitting the `align` modifier in the future easier.
* emit alignment modifier
This is required for correctly implementing `CheckedBitPattern` because
we need the layout of the type and its `Bits` type to have the same
layout.
* add unit test for `#[repr]` parsing
* allow multiple alignment modifiers
According to RFC #1358, if multiple alignment modifiers are specified,
the resulting alignment is the maximum of all alignment modifiers.
* actually return the error we just created
* factor out the integer Repr's into their own type
This is a preparation step for adding support for `#[repr(C, int)]`.
* allow parsing `#[repr(C, int)]`
This can be used on enums with fields.
* derive `CheckedBitPattern` for enums with fields
The implementation mostly mirrors the desugaring described at
https://doc.rust-lang.org/reference/type-layout.html
* add comments and rename some idents
* update error message
* update docs for `CheckedBitPattern` derive
* add new nested test case, change generated type naming scheme
* fix wrong comment
* small nit
---------
Co-authored-by: Gray Olson <gray@grayolson.com>
`from_integer` and `into_integer` are usually provided by the trait's
default implementation. We override this implementation because it goes
through `transmute_copy`, which can lead to inefficient assembly as seen
in https://github.com/Lokathor/bytemuck/issues/175 .
Doctests only run in the crate proper; doctests inside of integration tests are not run.
Move the existing doctests from derive/tests/basic.rs to derive/lib.rs, expanding them to make them
better for documentation as well.
* Add space because rust-analyzer thinks it's a weird literal otherwise.
* Add custom bounds for Zeroable.
* Cleanup custom bounds code.
* Only parse explicit bounds for Zeroable.
* Qualify syn types.
* If no explicit bounds are given, apply the default bounds.
* Add perfect derive semantics to `#[zeroable(bound = "...")]`.
This upgrades the derives from `syn` 1.0 to `syn` 2.0. While the MSRV
for `syn` 2.0 is not Rust 1.56 which is higher than the MSRV of
`bytemuck`, the derives don't fall under the MSRV policy.
Uses the compiler to check that all non-wrapped fields are actually 1-ZSTs,
and uses Zeroable to check that all non-wrapped fields are "conjurable".
Additionally, relaxes the bound of `PhantomData<T: Zeroable>: Zeroable` to all `T: ?Sized`.
* parse `repr(usize)` and `repr(isize)`
This can be used with enums.
* emit packed repr without type suffix
Previously we emitted the packed attribute with a type suffix for the
value `packed(4u32)`. This is not allowed. Instead we should emit
`packed(4)`.
* read bits instead of creating reference
This is required for packed structs where creating a reference to
fields is not allowed. We can make a copy of the bits because the bits
are `AnyBitPattern` which implies `Copy`.
* emit generics on implied traits
* Implement `ByteEq` and `ByteHash` derives
This adds the derives `ByteEq` and `ByteHash` that can be used as an
alternative to the `Eq` / `PartialEq` and `Hash` derives from the
standard library. The difference is that these variants use `bytemuck`
to convert their values to byte slices before comparing / hashing them.
This allows the comparisons to turn into a simple `memcmp` / `bcmp` (or
completely inlined as a few vector instructions) and allows hashers to
process all bytes at once, possibly allowing for some vector operations
as well.
Here's a quick comparison of the generated assembly:
![https://i.imgur.com/CGTSWTZ.png](https://i.imgur.com/CGTSWTZ.png)
* Address review comments
It seems like a copy-paste error has happened between `try_from_bytes`/`try_from_bytes_mut` and `try_pod_read_unaligned`, causing `internal::try_pod_read_unaligned` to try to read a &T::Bits instead of a T::Bits, usually failing with a `SizeMismatch` error. In the worst case, this allows UB in safe code by having a type allowing any bit pattern and being pointer-sized.