Skip to content

Commit

Permalink
Add support for data-carrying enums
Browse files Browse the repository at this point in the history
The primary feature of this change is adding support for deriving
zerocopy's traits on data-carrying enums. Along with that, it has a few
other features:

- Adds support for enums with repr(C, int)
- Improves zero discriminant detection for enums with negative
  discriminants
- For development, adds a VSCode config so we can prevent rust-analyzer
  from choking on our tests with enums that have thousands of variants
  • Loading branch information
djkoloski committed Jul 16, 2024
1 parent 1336f4b commit fae2247
Show file tree
Hide file tree
Showing 14 changed files with 2,213 additions and 401 deletions.
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rust-analyzer.check.extraEnv": {
"RUSTFLAGS": "--cfg rust_analyzer",
}
}
16 changes: 12 additions & 4 deletions src/macro_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ macro_rules! align_of {
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
#[macro_export]
macro_rules! struct_has_padding {
($t:ty, $($ts:ty),*) => {
($t:ty, [$($ts:ty),*]) => {
::zerocopy::macro_util::core_reexport::mem::size_of::<$t>() > 0 $(+ ::zerocopy::macro_util::core_reexport::mem::size_of::<$ts>())*
};
}
Expand All @@ -294,11 +294,19 @@ macro_rules! struct_has_padding {
#[doc(hidden)] // `#[macro_export]` bypasses this module's `#[doc(hidden)]`.
#[macro_export]
macro_rules! union_has_padding {
($t:ty, $($ts:ty),*) => {
($t:ty, [$($ts:ty),*]) => {
false $(|| ::zerocopy::macro_util::core_reexport::mem::size_of::<$t>() != ::zerocopy::macro_util::core_reexport::mem::size_of::<$ts>())*
};
}

#[doc(hidden)]
#[macro_export]
macro_rules! enum_has_padding {
($t:ty, $disc:ty, $([$($ts:ty),*]),*) => {
false $(|| ::zerocopy::macro_util::core_reexport::mem::size_of::<$t>() != (::zerocopy::macro_util::core_reexport::mem::size_of::<$disc>() $(+ ::zerocopy::macro_util::core_reexport::mem::size_of::<$ts>())*))*
}
}

/// Does `t` have alignment greater than or equal to `u`? If not, this macro
/// produces a compile error. It must be invoked in a dead codepath. This is
/// used in `transmute_ref!` and `transmute_mut!`.
Expand Down Expand Up @@ -728,7 +736,7 @@ mod tests {
(#[$cfg:meta] ($($ts:ty),*) => $expect:expr) => {{
#[$cfg]
struct Test($(#[allow(dead_code)] $ts),*);
assert_eq!(struct_has_padding!(Test, $($ts),*), $expect);
assert_eq!(struct_has_padding!(Test, [$($ts),*]), $expect);
}};
(#[$cfg:meta] $(#[$cfgs:meta])* ($($ts:ty),*) => $expect:expr) => {
test!(#[$cfg] ($($ts),*) => $expect);
Expand Down Expand Up @@ -759,7 +767,7 @@ mod tests {
#[$cfg]
#[allow(unused)] // fields are never read
union Test{ $($fs: $ts),* }
assert_eq!(union_has_padding!(Test, $($ts),*), $expect);
assert_eq!(union_has_padding!(Test, [$($ts),*]), $expect);
}};
(#[$cfg:meta] $(#[$cfgs:meta])* {$($fs:ident: $ts:ty),*} => $expect:expr) => {
test!(#[$cfg] {$($fs: $ts),*} => $expect);
Expand Down
Loading

0 comments on commit fae2247

Please sign in to comment.