Skip to content

Commit

Permalink
Merge branch 'main' into more-transparentwrapper-impls
Browse files Browse the repository at this point in the history
  • Loading branch information
Lokathor authored Oct 31, 2024
2 parents ee64218 + 79a15d0 commit 94acd77
Show file tree
Hide file tree
Showing 12 changed files with 414 additions and 173 deletions.
52 changes: 34 additions & 18 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bytemuck"
description = "A crate for mucking around with piles of bytes."
version = "1.17.1"
version = "1.19.0"
authors = ["Lokathor <[email protected]>"]
repository = "https://github.com/Lokathor/bytemuck"
readme = "README.md"
Expand All @@ -13,10 +13,16 @@ exclude = ["/pedantic.bat"]

[features]
# In v2 we'll fix these names to be more "normal".

# Enable deriving the various `bytemuck` traits.
derive = ["bytemuck_derive"]
# Enable features requiring items from `extern crate alloc`.
extern_crate_alloc = []
# Enable features requiring items from `extern crate std`.
extern_crate_std = ["extern_crate_alloc"]
# Implement `Zeroable` for `MaybeUninit`.
zeroable_maybe_uninit = []
# Implement `Zeroable` for `std::sync::atomic` types.
zeroable_atomics = []

# All MSRV notes below are GUIDELINES and future versions may require even more
Expand Down Expand Up @@ -44,8 +50,32 @@ const_zeroed = [] # MSRV 1.75.0: support const `zeroed()`
# Do not use if you can avoid it, because this is **unsound**!!!!
unsound_ptr_pod_impl = []

# NOT SEMVER SUPPORTED! TEMPORARY ONLY!
# MSRV 1.46.0: adds the `#[track_caller]` attribute to functions which may panic
track_caller = []

# Enables all features that are both sound and supported on the latest stable
# version of Rust, with the exception of `extern_crate_alloc` and
# `extern_crate_std`.
# Note: Enabling this feature opts out of any MSRV guarantees!
latest_stable_rust = [
# Keep this list sorted.
"aarch64_simd",
"align_offset",
"const_zeroed",
"derive",
"min_const_generics",
"must_cast",
"track_caller",
"wasm_simd",
"zeroable_atomics",
"zeroable_maybe_uninit",
]

# ALL FEATURES BELOW THIS ARE NOT SEMVER SUPPORTED! TEMPORARY ONLY!

# Enable support for `std::simd` types.
nightly_portable_simd = []
# Enable support for unstable `std::arch` types (such as the AVX512 types).
nightly_stdsimd = []
# Enable `f16` and `f128`
nightly_float = []
Expand All @@ -63,29 +93,15 @@ unexpected_cfgs = { level = "deny", check-cfg = ['cfg(target_arch, values("spirv
# Note(Lokathor): Don't use all-features or it would use `unsound_ptr_pod_impl` too.
features = [
"nightly_docs",
"derive",
"latest_stable_rust",
"extern_crate_alloc",
"extern_crate_std",
"zeroable_maybe_uninit",
"zeroable_atomics",
"min_const_generics",
"wasm_simd",
"must_cast",
"transparentwrapper_extra",
"const_zeroed",
]

[package.metadata.playground]
# Note(Lokathor): Don't use all-features or it would use `unsound_ptr_pod_impl` too.
features = [
"derive",
"latest_stable_rust",
"extern_crate_alloc",
"extern_crate_std",
"zeroable_maybe_uninit",
"zeroable_atomics",
"min_const_generics",
"wasm_simd",
"must_cast",
"transparentwrapper_extra",
"const_zeroed",
]
8 changes: 8 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# `bytemuck` changelog

## 1.19

* Adds the `#[track_caller]` attribute to functions which may panic.

## 1.18

* Adds the `latest_stable_rust` cargo feature, which is a blanket feature that turns all other features on that are both sound and compatible with Stable rust.

## 1.17.1

* Adds `#[repr(C)]` to the `union Transmute<A, B>` type that's used internally
Expand Down
2 changes: 1 addition & 1 deletion derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "bytemuck_derive"
description = "derive proc-macros for `bytemuck`"
version = "1.7.1"
version = "1.8.0"
authors = ["Lokathor <[email protected]>"]
repository = "https://github.com/Lokathor/bytemuck"
readme = "README.md"
Expand Down
4 changes: 4 additions & 0 deletions derive/changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@

## `bytemuck_derive` changelog

## 1.8

* [#257](https://github.com/Lokathor/bytemuck/pull/257): Allows deriving Zeroable on some enums.

## 1.7.1

* Adds the `bytemuck` attribute to the `NoUninit` derive, allowing it to be used when re-exported.
Expand Down
74 changes: 60 additions & 14 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,26 @@ pub fn derive_anybitpattern(
proc_macro::TokenStream::from(expanded)
}

/// Derive the `Zeroable` trait for a struct
/// Derive the `Zeroable` trait for a type.
///
/// The macro ensures that the struct follows all the the safety requirements
/// The macro ensures that the type follows all the the safety requirements
/// for the `Zeroable` trait.
///
/// The following constraints need to be satisfied for the macro to succeed
/// The following constraints need to be satisfied for the macro to succeed on a
/// struct:
///
/// - All fields in the struct must implement `Zeroable`
///
/// The following constraints need to be satisfied for the macro to succeed on
/// an enum:
///
/// - All fields in the struct must to implement `Zeroable`
/// - The enum has an explicit `#[repr(Int)]`, `#[repr(C)]`, or `#[repr(C,
/// Int)]`.
/// - The enum has a variant with discriminant 0 (explicitly or implicitly).
/// - All fields in the variant with discriminant 0 (if any) must implement
/// `Zeroable`
///
/// The macro always succeeds on unions.
///
/// ## Example
///
Expand All @@ -134,6 +146,23 @@ pub fn derive_anybitpattern(
/// b: u16,
/// }
/// ```
/// ```rust
/// # use bytemuck_derive::{Zeroable};
/// #[derive(Copy, Clone, Zeroable)]
/// #[repr(i32)]
/// enum Values {
/// A = 0,
/// B = 1,
/// C = 2,
/// }
/// #[derive(Clone, Zeroable)]
/// #[repr(C)]
/// enum Implicit {
/// A(bool, u8, char),
/// B(String),
/// C(std::num::NonZeroU8),
/// }
/// ```
///
/// # Custom bounds
///
Expand All @@ -157,6 +186,18 @@ pub fn derive_anybitpattern(
///
/// AlwaysZeroable::<std::num::NonZeroU8>::zeroed();
/// ```
/// ```rust
/// # use bytemuck::{Zeroable};
/// #[derive(Copy, Clone, Zeroable)]
/// #[repr(u8)]
/// #[zeroable(bound = "")]
/// enum MyOption<T> {
/// None,
/// Some(T),
/// }
///
/// assert!(matches!(MyOption::<std::num::NonZeroU8>::zeroed(), MyOption::None));
/// ```
///
/// ```rust,compile_fail
/// # use bytemuck::Zeroable;
Expand Down Expand Up @@ -407,7 +448,8 @@ pub fn derive_byte_eq(
let input = parse_macro_input!(input as DeriveInput);
let crate_name = bytemuck_crate_name(&input);
let ident = input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let (impl_generics, ty_generics, where_clause) =
input.generics.split_for_impl();

proc_macro::TokenStream::from(quote! {
impl #impl_generics ::core::cmp::PartialEq for #ident #ty_generics #where_clause {
Expand Down Expand Up @@ -460,7 +502,8 @@ pub fn derive_byte_hash(
let input = parse_macro_input!(input as DeriveInput);
let crate_name = bytemuck_crate_name(&input);
let ident = input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let (impl_generics, ty_generics, where_clause) =
input.generics.split_for_impl();

proc_macro::TokenStream::from(quote! {
impl #impl_generics ::core::hash::Hash for #ident #ty_generics #where_clause {
Expand Down Expand Up @@ -569,26 +612,29 @@ fn derive_marker_trait_inner<Trait: Derivable>(
.flatten()
.collect::<Vec<syn::WherePredicate>>();

let predicates = &mut input.generics.make_where_clause().predicates;

predicates.extend(explicit_bounds);

let fields = match &input.data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => fields.clone(),
syn::Data::Union(_) => {
let fields = match (Trait::perfect_derive_fields(&input), &input.data) {
(Some(fields), _) => fields,
(None, syn::Data::Struct(syn::DataStruct { fields, .. })) => {
fields.clone()
}
(None, syn::Data::Union(_)) => {
return Err(syn::Error::new_spanned(
trait_,
&"perfect derive is not supported for unions",
));
}
syn::Data::Enum(_) => {
(None, syn::Data::Enum(_)) => {
return Err(syn::Error::new_spanned(
trait_,
&"perfect derive is not supported for enums",
));
}
};

let predicates = &mut input.generics.make_where_clause().predicates;

predicates.extend(explicit_bounds);

for field in fields {
let ty = field.ty;
predicates.push(syn::parse_quote!(
Expand Down
Loading

0 comments on commit 94acd77

Please sign in to comment.