From 1fb245c926a9a7bdf99d5911dc741945c0e96728 Mon Sep 17 00:00:00 2001 From: Gray Olson Date: Tue, 29 Mar 2022 20:25:51 -0700 Subject: [PATCH] rename NoPadding to NoUninit and clarify docs (#95) --- derive/src/lib.rs | 20 +++++++-------- derive/src/traits.rs | 20 +++++++-------- derive/tests/basic.rs | 14 +++++------ src/allocation.rs | 10 ++++---- src/anybitpattern.rs | 6 ++--- src/checked.rs | 40 +++++++++++++++--------------- src/lib.rs | 38 ++++++++++++++-------------- src/{nopadding.rs => no_uninit.rs} | 24 +++++++++--------- src/pod.rs | 2 +- 9 files changed, 87 insertions(+), 87 deletions(-) rename src/{nopadding.rs => no_uninit.rs} (68%) diff --git a/derive/src/lib.rs b/derive/src/lib.rs index bbbdf9d..27b91f9 100644 --- a/derive/src/lib.rs +++ b/derive/src/lib.rs @@ -9,7 +9,7 @@ use quote::{quote, quote_spanned}; use syn::{parse_macro_input, DeriveInput, spanned::Spanned}; use crate::traits::{ - AnyBitPattern, Contiguous, Derivable, CheckedBitPattern, NoPadding, Pod, TransparentWrapper, Zeroable, + AnyBitPattern, Contiguous, Derivable, CheckedBitPattern, NoUninit, Pod, TransparentWrapper, Zeroable, }; /// Derive the `Pod` trait for a struct @@ -93,17 +93,17 @@ pub fn derive_zeroable( proc_macro::TokenStream::from(expanded) } -/// Derive the `NoPadding` trait for a struct or enum +/// Derive the `NoUninit` trait for a struct or enum /// /// The macro ensures that the type follows all the the safety requirements -/// for the `NoPadding` trait. +/// for the `NoUninit` trait. /// /// The following constraints need to be satisfied for the macro to succeed -/// (the rest of the constraints are guaranteed by the `NoPadding` subtrait bounds, +/// (the rest of the constraints are guaranteed by the `NoUninit` subtrait bounds, /// i.e. the type must be `Sized + Copy + 'static`): /// /// If applied to a struct: -/// - All fields in the struct must implement `NoPadding` +/// - All fields in the struct must implement `NoUninit` /// - The struct must be `#[repr(C)]` or `#[repr(transparent)]` /// - The struct must not contain any padding bytes /// - The struct must contain no generic parameters @@ -112,12 +112,12 @@ pub fn derive_zeroable( /// - The enum must be explicit `#[repr(Int)]` /// - All variants must be fieldless /// - The enum must contain no generic parameters -#[proc_macro_derive(NoPadding)] -pub fn derive_no_padding( +#[proc_macro_derive(NoUninit)] +pub fn derive_no_uninit( input: proc_macro::TokenStream, ) -> proc_macro::TokenStream { let expanded = - derive_marker_trait::(parse_macro_input!(input as DeriveInput)); + derive_marker_trait::(parse_macro_input!(input as DeriveInput)); proc_macro::TokenStream::from(expanded) } @@ -130,14 +130,14 @@ pub fn derive_no_padding( /// /// The following constraints need to be satisfied for the macro to succeed /// (the rest of the constraints are guaranteed by the `CheckedBitPattern` subtrait bounds, -/// i.e. are guaranteed by the requirements of the `NoPadding` trait which `CheckedBitPattern` +/// i.e. are guaranteed by the requirements of the `NoUninit` trait which `CheckedBitPattern` /// is a subtrait of): /// /// If applied to a struct: /// - All fields must implement `CheckedBitPattern` /// /// If applied to an enum: -/// - All requirements already checked by `NoPadding`, just impls the trait +/// - All requirements already checked by `NoUninit`, just impls the trait #[proc_macro_derive(CheckedBitPattern)] pub fn derive_maybe_pod( input: proc_macro::TokenStream, diff --git a/derive/src/traits.rs b/derive/src/traits.rs index 38ba919..c5f8bcb 100644 --- a/derive/src/traits.rs +++ b/derive/src/traits.rs @@ -107,11 +107,11 @@ impl Derivable for Zeroable { } } -pub struct NoPadding; +pub struct NoUninit; -impl Derivable for NoPadding { +impl Derivable for NoUninit { fn ident() -> TokenStream { - quote!(::bytemuck::NoPadding) + quote!(::bytemuck::NoUninit) } fn check_attributes( @@ -121,20 +121,20 @@ impl Derivable for NoPadding { match ty { Data::Struct(_) => match repr.as_deref() { Some("C" | "transparent") => Ok(()), - _ => Err("NoPadding derive requires the type to be #[repr(C)] or #[repr(transparent)]"), + _ => Err("NoUninit requires the struct to be #[repr(C)] or #[repr(transparent)]"), }, Data::Enum(_) => if repr.map(|repr| repr.starts_with('u') || repr.starts_with('i')) == Some(true) { Ok(()) } else { - Err("NoPadding requires the enum to be an explicit #[repr(Int)]") + Err("NoUninit requires the enum to be an explicit #[repr(Int)]") }, - Data::Union(_) => Err("NoPadding cannot be derived for unions") + Data::Union(_) => Err("NoUninit can only be derived on enums and structs") } } fn asserts(input: &DeriveInput) -> Result { if !input.generics.params.is_empty() { - return Err("NoPadding cannot be derived for structs containing generic parameters because the padding requirements can't be verified for generic structs"); + return Err("NoUninit cannot be derived for structs containing generic parameters because the padding requirements can't be verified for generic structs"); } match &input.data { @@ -150,12 +150,12 @@ impl Derivable for NoPadding { } Data::Enum(DataEnum { variants, .. }) => { if variants.iter().any(|variant| !variant.fields.is_empty()) { - Err("Only fieldless enums are supported for NoPadding") + Err("Only fieldless enums are supported for NoUninit") } else { Ok(quote!()) } } - Data::Union(_) => Err("NoPadding cannot be derived for unions") + Data::Union(_) => Err("NoUninit cannot be derived for unions"), // shouldn't be possible since we already error in attribute check for this case } } @@ -203,7 +203,7 @@ impl Derivable for CheckedBitPattern { Ok(assert_fields_are_maybe_pod) } - Data::Enum(_) => Ok(quote!()), // nothing needed, already guaranteed OK by NoPadding + Data::Enum(_) => Ok(quote!()), // nothing needed, already guaranteed OK by NoUninit Data::Union(_) => Err("Internal error in CheckedBitPattern derive"), // shouldn't be possible since we already error in attribute check for this case } } diff --git a/derive/tests/basic.rs b/derive/tests/basic.rs index 252ce02..456266d 100644 --- a/derive/tests/basic.rs +++ b/derive/tests/basic.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] use bytemuck::{ - Contiguous, CheckedBitPattern, NoPadding, Pod, TransparentWrapper, Zeroable, AnyBitPattern, + AnyBitPattern, Contiguous, CheckedBitPattern, NoUninit, Pod, TransparentWrapper, Zeroable, }; use std::marker::PhantomData; @@ -51,9 +51,9 @@ enum ContiguousWithImplicitValues { E, } -#[derive(Copy, Clone, NoPadding)] +#[derive(Copy, Clone, NoUninit)] #[repr(C)] -struct NoPaddingTest { +struct NoUninitTest { a: u16, b: u16, } @@ -66,7 +66,7 @@ union UnionTestAnyBitPattern { } #[repr(u8)] -#[derive(Debug, Clone, Copy, NoPadding, CheckedBitPattern, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, NoUninit, CheckedBitPattern, PartialEq, Eq)] enum CheckedBitPatternEnumWithValues { A = 0, B = 1, @@ -76,7 +76,7 @@ enum CheckedBitPatternEnumWithValues { } #[repr(i8)] -#[derive(Clone, Copy, NoPadding, CheckedBitPattern)] +#[derive(Clone, Copy, NoUninit, CheckedBitPattern)] enum CheckedBitPatternEnumWithImplicitValues { A = -10, B, @@ -86,7 +86,7 @@ enum CheckedBitPatternEnumWithImplicitValues { } #[repr(u8)] -#[derive(Debug, Clone, Copy, NoPadding, CheckedBitPattern, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, NoUninit, CheckedBitPattern, PartialEq, Eq)] enum CheckedBitPatternEnumNonContiguous { A = 1, B = 8, @@ -95,7 +95,7 @@ enum CheckedBitPatternEnumNonContiguous { E = 56, } -#[derive(Debug, Copy, Clone, NoPadding, CheckedBitPattern, PartialEq, Eq)] +#[derive(Debug, Copy, Clone, NoUninit, CheckedBitPattern, PartialEq, Eq)] #[repr(C)] struct CheckedBitPatternStruct { a: u8, diff --git a/src/allocation.rs b/src/allocation.rs index 0ce5dbd..b6aa8b6 100644 --- a/src/allocation.rs +++ b/src/allocation.rs @@ -18,7 +18,7 @@ use core::convert::TryInto; /// As [`try_cast_box`](try_cast_box), but unwraps for you. #[inline] -pub fn cast_box(input: Box) -> Box { +pub fn cast_box(input: Box) -> Box { try_cast_box(input).map_err(|(e, _v)| e).unwrap() } @@ -32,7 +32,7 @@ pub fn cast_box(input: Box) -> Box { /// alignment. /// * The start and end size of the `Box` must have the exact same size. #[inline] -pub fn try_cast_box( +pub fn try_cast_box( input: Box, ) -> Result, (PodCastError, Box)> { if align_of::() != align_of::() { @@ -139,7 +139,7 @@ pub fn zeroed_slice_box(length: usize) -> Box<[T]> { /// As [`try_cast_vec`](try_cast_vec), but unwraps for you. #[inline] -pub fn cast_vec(input: Vec) -> Vec { +pub fn cast_vec(input: Vec) -> Vec { try_cast_vec(input).map_err(|(e, _v)| e).unwrap() } @@ -156,7 +156,7 @@ pub fn cast_vec(input: Vec) -> Vec { /// capacity and length get adjusted during transmutation, but for now it's /// absolute. #[inline] -pub fn try_cast_vec( +pub fn try_cast_vec( input: Vec, ) -> Result, (PodCastError, Vec)> { if align_of::() != align_of::() { @@ -199,7 +199,7 @@ pub fn try_cast_vec( /// assert_eq!(&vec_of_words[..], &[0x0005_0006, 0x0007_0008][..]) /// } /// ``` -pub fn pod_collect_to_vec(src: &[A]) -> Vec { +pub fn pod_collect_to_vec(src: &[A]) -> Vec { let src_size = size_of_val(src); // Note(Lokathor): dst_count is rounded up so that the dest will always be at // least as many bytes as the src. diff --git a/src/anybitpattern.rs b/src/anybitpattern.rs index ac9aecd..2984db2 100644 --- a/src/anybitpattern.rs +++ b/src/anybitpattern.rs @@ -3,9 +3,9 @@ use crate::{Pod, Zeroable}; /// Marker trait for "plain old data" types that are valid for any bit pattern. /// /// The requirements for this is very similar to [`Pod`], -/// except that it doesn't require that the type contains no padding bytes. +/// except that it doesn't require that the type contains no uninit (or padding) bytes. /// This limits what you can do with a type of this kind, but also broadens the -/// included types to `repr(C)` structs that contain padding. Notably, you can only cast +/// included types to `repr(C)` `struct`s that contain padding as well as `union`s. Notably, you can only cast /// *immutable* references and *owned* values into [`AnyBitPattern`] types, not /// *mutable* references. /// @@ -29,7 +29,7 @@ use crate::{Pod, Zeroable}; /// /// # Safety /// -/// Similar to [`Pod`] except we disregard the rule about it must not contain padding. +/// Similar to [`Pod`] except we disregard the rule about it must not contain uninit bytes. /// Still, this is a quite strong guarantee about a type, so *be careful* when /// implementing it manually. /// diff --git a/src/checked.rs b/src/checked.rs index ad86a57..6ac36c8 100644 --- a/src/checked.rs +++ b/src/checked.rs @@ -1,7 +1,7 @@ //! Checked versions of the casting functions exposed in crate root //! that support [`CheckedBitPattern`] types. -use crate::{internal::{self, something_went_wrong}, NoPadding, AnyBitPattern}; +use crate::{internal::{self, something_went_wrong}, NoUninit, AnyBitPattern}; /// A marker trait that allows types that have some invalid bit patterns to be used /// in places that otherwise require [`AnyBitPattern`] or [`Pod`] types by performing @@ -33,7 +33,7 @@ use crate::{internal::{self, something_went_wrong}, NoPadding, AnyBitPattern}; /// If manually implementing the trait, we can do something like so: /// /// ```rust -/// use bytemuck::{CheckedBitPattern, NoPadding}; +/// use bytemuck::{CheckedBitPattern, NoUninit}; /// /// #[repr(u32)] /// #[derive(Copy, Clone)] @@ -54,16 +54,16 @@ use crate::{internal::{self, something_went_wrong}, NoPadding, AnyBitPattern}; /// } /// } /// -/// // It is often useful to also implement `NoPadding` on our `CheckedBitPattern` types. +/// // It is often useful to also implement `NoUninit` on our `CheckedBitPattern` types. /// // This will allow us to do casting of mutable references (and mutable slices). /// // It is not always possible to do so, but in this case we have no padding so it is. -/// unsafe impl NoPadding for MyEnum {} +/// unsafe impl NoUninit for MyEnum {} /// ``` /// /// We can now use relevant casting functions. For example, /// /// ```rust -/// # use bytemuck::{CheckedBitPattern, NoPadding}; +/// # use bytemuck::{CheckedBitPattern, NoUninit}; /// # #[repr(u32)] /// # #[derive(Copy, Clone, PartialEq, Eq, Debug)] /// # enum MyEnum { @@ -71,7 +71,7 @@ use crate::{internal::{self, something_went_wrong}, NoPadding, AnyBitPattern}; /// # Variant1 = 1, /// # Variant2 = 2, /// # } -/// # unsafe impl NoPadding for MyEnum {} +/// # unsafe impl NoUninit for MyEnum {} /// # unsafe impl CheckedBitPattern for MyEnum { /// # type Bits = u32; /// # fn is_valid_bit_pattern(bits: &u32) -> bool { @@ -93,8 +93,8 @@ use crate::{internal::{self, something_went_wrong}, NoPadding, AnyBitPattern}; /// let result = checked::try_from_bytes::(bytes); /// assert!(result.is_err()); /// -/// // Since we implemented NoPadding, we can also cast mutably from an original type -/// // that is `NoPadding + AnyBitPattern`: +/// // Since we implemented NoUninit, we can also cast mutably from an original type +/// // that is `NoUninit + AnyBitPattern`: /// let mut my_u32 = 2u32; /// { /// let as_enum_mut = checked::cast_mut::<_, MyEnum>(&mut my_u32); @@ -214,7 +214,7 @@ pub fn try_from_bytes( /// * If the slice's length isn’t exactly the size of the new type /// * If the slice contains an invalid bit pattern for `T` #[inline] -pub fn try_from_bytes_mut( +pub fn try_from_bytes_mut( s: &mut [u8], ) -> Result<&mut T, CheckedCastError> { let pod = unsafe { internal::try_from_bytes_mut(s) }?; @@ -254,7 +254,7 @@ pub fn try_pod_read_unaligned(bytes: &[u8]) -> Result( +pub fn try_cast( a: A, ) -> Result { let pod = unsafe { internal::try_cast(a) }?; @@ -274,7 +274,7 @@ pub fn try_cast( /// * If the source type and target type aren't the same size. /// * If `a` contains an invalid bit pattern for `B` this fails. #[inline] -pub fn try_cast_ref( +pub fn try_cast_ref( a: &A, ) -> Result<&B, CheckedCastError> { let pod = unsafe { internal::try_cast_ref(a) }?; @@ -290,7 +290,7 @@ pub fn try_cast_ref( /// /// As [`checked_cast_ref`], but `mut`. #[inline] -pub fn try_cast_mut( +pub fn try_cast_mut( a: &mut A, ) -> Result<&mut B, CheckedCastError> { let pod = unsafe { internal::try_cast_mut(a) }?; @@ -319,7 +319,7 @@ pub fn try_cast_mut( +pub fn try_cast_slice( a: &[A], ) -> Result<&[B], CheckedCastError> { let pod = unsafe { internal::try_cast_slice(a) }?; @@ -338,7 +338,7 @@ pub fn try_cast_slice( /// /// As [`checked_cast_slice`], but `&mut`. #[inline] -pub fn try_cast_slice_mut( +pub fn try_cast_slice_mut( a: &mut [A], ) -> Result<&mut [B], CheckedCastError> { let pod = unsafe { internal::try_cast_slice_mut(a) }?; @@ -371,7 +371,7 @@ pub fn from_bytes(s: &[u8]) -> &T { /// /// This is [`try_from_bytes_mut`] but will panic on error. #[inline] -pub fn from_bytes_mut(s: &mut [u8]) -> &mut T { +pub fn from_bytes_mut(s: &mut [u8]) -> &mut T { match try_from_bytes_mut(s) { Ok(t) => t, Err(e) => something_went_wrong("from_bytes_mut", e), @@ -396,7 +396,7 @@ pub fn pod_read_unaligned(bytes: &[u8]) -> T { /// /// * This is like [`try_cast`](try_cast), but will panic on a size mismatch. #[inline] -pub fn cast(a: A) -> B { +pub fn cast(a: A) -> B { match try_cast(a) { Ok(t) => t, Err(e) => something_went_wrong("cast", e), @@ -409,7 +409,7 @@ pub fn cast(a: A) -> B { /// /// This is [`try_cast_mut`] but will panic on error. #[inline] -pub fn cast_mut(a: &mut A) -> &mut B { +pub fn cast_mut(a: &mut A) -> &mut B { match try_cast_mut(a) { Ok(t) => t, Err(e) => something_went_wrong("cast_mut", e), @@ -422,7 +422,7 @@ pub fn cast_mut( /// /// This is [`try_cast_ref`] but will panic on error. #[inline] -pub fn cast_ref(a: &A) -> &B { +pub fn cast_ref(a: &A) -> &B { match try_cast_ref(a) { Ok(t) => t, Err(e) => something_went_wrong("cast_ref", e), @@ -435,7 +435,7 @@ pub fn cast_ref(a: &A) -> &B { /// /// This is [`try_cast_slice`] but will panic on error. #[inline] -pub fn cast_slice(a: &[A]) -> &[B] { +pub fn cast_slice(a: &[A]) -> &[B] { match try_cast_slice(a) { Ok(t) => t, Err(e) => something_went_wrong("cast_slice", e), @@ -448,7 +448,7 @@ pub fn cast_slice(a: &[A]) -> &[B] { /// /// This is [`try_cast_slice_mut`] but will panic on error. #[inline] -pub fn cast_slice_mut(a: &mut [A]) -> &mut [B] { +pub fn cast_slice_mut(a: &mut [A]) -> &mut [B] { match try_cast_slice_mut(a) { Ok(t) => t, Err(e) => something_went_wrong("cast_slice_mut", e), diff --git a/src/lib.rs b/src/lib.rs index d4e814d..afd3684 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -94,8 +94,8 @@ pub use zeroable::*; mod pod; pub use pod::*; -mod nopadding; -pub use nopadding::*; +mod no_uninit; +pub use no_uninit::*; mod contiguous; pub use contiguous::*; @@ -108,7 +108,7 @@ pub use transparent::*; #[cfg(feature = "derive")] pub use bytemuck_derive::{ - AnyBitPattern, Contiguous, CheckedBitPattern, NoPadding, Pod, TransparentWrapper, Zeroable, + AnyBitPattern, Contiguous, CheckedBitPattern, NoUninit, Pod, TransparentWrapper, Zeroable, }; /// The things that can go wrong when casting between [`Pod`] data forms. @@ -147,7 +147,7 @@ impl std::error::Error for PodCastError {} /// Any ZST becomes an empty slice, and in that case the pointer value of that /// empty slice might not match the pointer value of the input reference. #[inline] -pub fn bytes_of(t: &T) -> &[u8] { +pub fn bytes_of(t: &T) -> &[u8] { unsafe { internal::bytes_of(t) } } @@ -156,7 +156,7 @@ pub fn bytes_of(t: &T) -> &[u8] { /// Any ZST becomes an empty slice, and in that case the pointer value of that /// empty slice might not match the pointer value of the input reference. #[inline] -pub fn bytes_of_mut(t: &mut T) -> &mut [u8] { +pub fn bytes_of_mut(t: &mut T) -> &mut [u8] { unsafe { internal::bytes_of_mut(t) } } @@ -176,7 +176,7 @@ pub fn from_bytes(s: &[u8]) -> &T { /// /// This is [`try_from_bytes_mut`] but will panic on error. #[inline] -pub fn from_bytes_mut(s: &mut [u8]) -> &mut T { +pub fn from_bytes_mut(s: &mut [u8]) -> &mut T { unsafe { internal::from_bytes_mut(s) } } @@ -216,7 +216,7 @@ pub fn try_from_bytes(s: &[u8]) -> Result<&T, PodCastError> { /// * If the slice isn't aligned for the new type /// * If the slice's length isn’t exactly the size of the new type #[inline] -pub fn try_from_bytes_mut( +pub fn try_from_bytes_mut( s: &mut [u8], ) -> Result<&mut T, PodCastError> { unsafe { internal::try_from_bytes_mut(s) } @@ -228,7 +228,7 @@ pub fn try_from_bytes_mut( /// /// * This is like [`try_cast`](try_cast), but will panic on a size mismatch. #[inline] -pub fn cast(a: A) -> B { +pub fn cast(a: A) -> B { unsafe { internal::cast(a) } } @@ -238,7 +238,7 @@ pub fn cast(a: A) -> B { /// /// This is [`try_cast_mut`] but will panic on error. #[inline] -pub fn cast_mut(a: &mut A) -> &mut B { +pub fn cast_mut(a: &mut A) -> &mut B { unsafe { internal::cast_mut(a) } } @@ -248,7 +248,7 @@ pub fn cast_mut(a: & /// /// This is [`try_cast_ref`] but will panic on error. #[inline] -pub fn cast_ref(a: &A) -> &B { +pub fn cast_ref(a: &A) -> &B { unsafe { internal::cast_ref(a) } } @@ -258,7 +258,7 @@ pub fn cast_ref(a: &A) -> &B { /// /// This is [`try_cast_slice`] but will panic on error. #[inline] -pub fn cast_slice(a: &[A]) -> &[B] { +pub fn cast_slice(a: &[A]) -> &[B] { unsafe { internal::cast_slice(a) } } @@ -268,19 +268,19 @@ pub fn cast_slice(a: &[A]) -> &[B] { /// /// This is [`try_cast_slice_mut`] but will panic on error. #[inline] -pub fn cast_slice_mut(a: &mut [A]) -> &mut [B] { +pub fn cast_slice_mut(a: &mut [A]) -> &mut [B] { unsafe { internal::cast_slice_mut(a) } } /// As `align_to`, but safe because of the [`Pod`] bound. #[inline] -pub fn pod_align_to(vals: &[T]) -> (&[T], &[U], &[T]) { +pub fn pod_align_to(vals: &[T]) -> (&[T], &[U], &[T]) { unsafe { vals.align_to::() } } /// As `align_to_mut`, but safe because of the [`Pod`] bound. #[inline] -pub fn pod_align_to_mut( +pub fn pod_align_to_mut( vals: &mut [T], ) -> (&mut [T], &mut [U], &mut [T]) { unsafe { vals.align_to_mut::() } @@ -297,7 +297,7 @@ pub fn pod_align_to_mut(a: A) -> Result { +pub fn try_cast(a: A) -> Result { unsafe { internal::try_cast(a) } } @@ -308,7 +308,7 @@ pub fn try_cast(a: A) -> Result /// * If the reference isn't aligned in the new type /// * If the source type and target type aren't the same size. #[inline] -pub fn try_cast_ref(a: &A) -> Result<&B, PodCastError> { +pub fn try_cast_ref(a: &A) -> Result<&B, PodCastError> { unsafe { internal::try_cast_ref(a) } } @@ -316,7 +316,7 @@ pub fn try_cast_ref(a: &A) -> Result<&B, PodCast /// /// As [`try_cast_ref`], but `mut`. #[inline] -pub fn try_cast_mut(a: &mut A) -> Result<&mut B, PodCastError> { +pub fn try_cast_mut(a: &mut A) -> Result<&mut B, PodCastError> { unsafe { internal::try_cast_mut(a) } } @@ -336,7 +336,7 @@ pub fn try_cast_mut( /// * Similarly, you can't convert between a [ZST](https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts) /// and a non-ZST. #[inline] -pub fn try_cast_slice(a: &[A]) -> Result<&[B], PodCastError> { +pub fn try_cast_slice(a: &[A]) -> Result<&[B], PodCastError> { unsafe { internal::try_cast_slice(a) } } @@ -345,7 +345,7 @@ pub fn try_cast_slice(a: &[A]) -> Result<&[B], P /// /// As [`try_cast_slice`], but `&mut`. #[inline] -pub fn try_cast_slice_mut( +pub fn try_cast_slice_mut( a: &mut [A], ) -> Result<&mut [B], PodCastError> { unsafe { internal::try_cast_slice_mut(a) } diff --git a/src/nopadding.rs b/src/no_uninit.rs similarity index 68% rename from src/nopadding.rs rename to src/no_uninit.rs index fbb47bc..8aeed66 100644 --- a/src/nopadding.rs +++ b/src/no_uninit.rs @@ -1,23 +1,23 @@ use crate::Pod; -/// Marker trait for "plain old data" types with no padding. +/// Marker trait for "plain old data" types with no uninit (or padding) bytes. /// /// The requirements for this is very similar to [`Pod`], /// except that it doesn't require that all bit patterns of the type are valid, i.e. /// it does not require the type to be [`Zeroable`][crate::Zeroable]. /// This limits what you can do with a type of this kind, but also broadens the /// included types to things like C-style enums. Notably, you can only cast from -/// *immutable* references to a [`NoPadding`] type into *immutable* references of any other +/// *immutable* references to a [`NoUninit`] type into *immutable* references of any other /// type, no casting of mutable references or mutable references to slices etc. /// -/// [`Pod`] is a subset of [`NoPadding`], meaning that any `T: Pod` is also -/// [`NoPadding`] but any `T: NoPadding` is not necessarily [`Pod`]. If possible, +/// [`Pod`] is a subset of [`NoUninit`], meaning that any `T: Pod` is also +/// [`NoUninit`] but any `T: NoUninit` is not necessarily [`Pod`]. If possible, /// prefer implementing [`Pod`] directly. To get more [`Pod`]-like functionality for -/// a type that is only [`NoPadding`], consider also implementing [`CheckedBitPattern`][crate::CheckedBitPattern]. +/// a type that is only [`NoUninit`], consider also implementing [`CheckedBitPattern`][crate::CheckedBitPattern]. /// /// # Derive /// -/// A `#[derive(NoPadding)]` macro is provided under the `derive` feature flag which will +/// A `#[derive(NoUninit)]` macro is provided under the `derive` feature flag which will /// automatically validate the requirements of this trait and implement the /// trait for you for both enums and structs. This is the recommended method for /// implementing the trait, however it's also possible to do manually. If you @@ -32,21 +32,21 @@ use crate::Pod; /// /// * The type must be inhabited (eg: no /// [Infallible](core::convert::Infallible)). -/// * The type must not contain any padding bytes, either in the middle or on +/// * The type must not contain any uninit (or padding) bytes, either in the middle or on /// the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has padding in the /// middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which has padding on /// the end). -/// * Structs need to have all fields also be `NoPadding`. +/// * Structs need to have all fields also be `NoUninit`. /// * Structs need to be `repr(C)` or `repr(transparent)`. In the case of /// `repr(C)`, the `packed` and `align` repr modifiers can be used as long as /// all other rules end up being followed. /// * Enums need to have an explicit `#[repr(Int)]` /// * Enums must have only fieldless variants /// * There's probably more, don't mess it up (I mean it). -pub unsafe trait NoPadding: Sized + Copy + 'static {} +pub unsafe trait NoUninit: Sized + Copy + 'static {} -unsafe impl NoPadding for T {} +unsafe impl NoUninit for T {} -unsafe impl NoPadding for char {} +unsafe impl NoUninit for char {} -unsafe impl NoPadding for bool {} +unsafe impl NoUninit for bool {} diff --git a/src/pod.rs b/src/pod.rs index 28618d3..085f8d3 100644 --- a/src/pod.rs +++ b/src/pod.rs @@ -18,7 +18,7 @@ use super::*; /// [Infallible](core::convert::Infallible)). /// * The type must allow any bit pattern (eg: no `bool` or `char`, which have /// illegal bit patterns). -/// * The type must not contain any padding bytes, either in the middle or on +/// * The type must not contain any uninit (or padding) bytes, either in the middle or on /// the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has padding in the /// middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which has padding on /// the end).