diff --git a/src/lib.rs b/src/lib.rs index 6f21fc398a9..15a8b87c624 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3967,12 +3967,12 @@ safety_comment! { assert_unaligned!(PhantomData<()>, PhantomData, PhantomData); } -impl_for_transparent_wrapper!(T: NoCell => NoCell for Wrapping); -impl_for_transparent_wrapper!(T: TryFromBytes => TryFromBytes for Wrapping); -impl_for_transparent_wrapper!(T: FromZeros => FromZeros for Wrapping); -impl_for_transparent_wrapper!(T: FromBytes => FromBytes for Wrapping); -impl_for_transparent_wrapper!(T: IntoBytes => IntoBytes for Wrapping); -impl_for_transparent_wrapper!(T: Unaligned => Unaligned for Wrapping); +impl_for_transparent_wrapper!(T => NoCell for Wrapping [T]); +impl_for_transparent_wrapper!(T => TryFromBytes for Wrapping [T]); +impl_for_transparent_wrapper!(T => FromZeros for Wrapping [T]); +impl_for_transparent_wrapper!(T => FromBytes for Wrapping [T]); +impl_for_transparent_wrapper!(T => IntoBytes for Wrapping [T]); +impl_for_transparent_wrapper!(T => Unaligned for Wrapping [T]); assert_unaligned!(Wrapping<()>, Wrapping); safety_comment! { @@ -3984,23 +3984,23 @@ safety_comment! { unsafe_impl!(T => FromBytes for MaybeUninit); } -impl_for_transparent_wrapper!(T: NoCell => NoCell for MaybeUninit); -impl_for_transparent_wrapper!(T: Unaligned => Unaligned for MaybeUninit); +impl_for_transparent_wrapper!(T => NoCell for MaybeUninit [T]); +impl_for_transparent_wrapper!(T => Unaligned for MaybeUninit [T]); assert_unaligned!(MaybeUninit<()>, MaybeUninit); -impl_for_transparent_wrapper!(T: ?Sized + NoCell => NoCell for ManuallyDrop); -impl_for_transparent_wrapper!(T: ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop); -impl_for_transparent_wrapper!(T: ?Sized + FromZeros => FromZeros for ManuallyDrop); -impl_for_transparent_wrapper!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop); -impl_for_transparent_wrapper!(T: ?Sized + IntoBytes => IntoBytes for ManuallyDrop); -impl_for_transparent_wrapper!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop); +impl_for_transparent_wrapper!(T: ?Sized => NoCell for ManuallyDrop [T]); +impl_for_transparent_wrapper!(T: ?Sized => TryFromBytes for ManuallyDrop [T]); +impl_for_transparent_wrapper!(T: ?Sized => FromZeros for ManuallyDrop [T]); +impl_for_transparent_wrapper!(T: ?Sized => FromBytes for ManuallyDrop [T]); +impl_for_transparent_wrapper!(T: ?Sized => IntoBytes for ManuallyDrop [T]); +impl_for_transparent_wrapper!(T: ?Sized => Unaligned for ManuallyDrop [T]); assert_unaligned!(ManuallyDrop<()>, ManuallyDrop); // TODO(#5): Implement `FromZeros` and `FromBytes` when `T: ?Sized`. -impl_for_transparent_wrapper!(T: FromZeros => FromZeros for UnsafeCell); -impl_for_transparent_wrapper!(T: FromBytes => FromBytes for UnsafeCell); -impl_for_transparent_wrapper!(T: ?Sized + IntoBytes => IntoBytes for UnsafeCell); -impl_for_transparent_wrapper!(T: ?Sized + Unaligned => Unaligned for UnsafeCell); +impl_for_transparent_wrapper!(T => FromZeros for UnsafeCell [T]); +impl_for_transparent_wrapper!(T => FromBytes for UnsafeCell [T]); +impl_for_transparent_wrapper!(T: ?Sized => IntoBytes for UnsafeCell [T]); +impl_for_transparent_wrapper!(T: ?Sized => Unaligned for UnsafeCell [T]); assert_unaligned!(UnsafeCell<()>, UnsafeCell); // SAFETY: See safety comment in `is_bit_valid` impl. diff --git a/src/macros.rs b/src/macros.rs index 317eebf5361..ae49e8e7535 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -202,13 +202,13 @@ macro_rules! unsafe_impl { macro_rules! impl_for_transparent_wrapper { ( $(#[$attr:meta])* - $tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )? - => $trait:ident for $ty:ty $(; |$candidate:ident $(: MaybeAligned<$ref_repr:ty>)? $(: Maybe<$ptr_repr:ty>)?| $is_bit_valid:expr)? + $($tyvar:ident $(: $(? $optbound:ident $(+)?)* $($bound:ident $(+)?)* )?)? => + $trait:ident for $ty:ty [$inner:ty] ) => { $(#[$attr])* #[allow(non_local_definitions)] // SAFETY: - // - We explicitly add a `$tyvar: $trait` bound (regardless of what + // - We explicitly add a `$inner: $trait` bound (regardless of what // bounds the caller has provided). // - Inside of `only_derive_is_allowed_to_implement_this_trait`, `f` is // generic over the any `I: Invariants`, and is generic over the same @@ -228,74 +228,32 @@ macro_rules! impl_for_transparent_wrapper { // // Each `@is_transparent_wrapper` arm contains its own safety comment // which explains why its bounds are sound. - unsafe impl<$tyvar: $($(? $optbound +)* $($bound +)*)? $trait> $trait for $ty { + unsafe impl<$($tyvar: $($(? $optbound +)* $($bound +)*)?)?> $trait for $ty where + $inner: $trait + { #[allow(dead_code, clippy::missing_inline_in_public_items)] fn only_derive_is_allowed_to_implement_this_trait() { use crate::{pointer::invariant::Invariants, util::*}; impl_for_transparent_wrapper!(@is_transparent_wrapper $trait); - fn f() { - is_transparent_wrapper::(); + fn f() { + is_transparent_wrapper::(); } } impl_for_transparent_wrapper!( @is_bit_valid - <$tyvar: $($(? $optbound +)* $($bound +)*)?> + $(<$tyvar: $($(? $optbound +)* $($bound +)*)?>)? $trait for $ty ); } }; ( $(#[$attr:meta])* - for $ty:ty [$inner:ty] $(; |$candidate:ident $(: MaybeAligned<$ref_repr:ty>)? $(: Maybe<$ptr_repr:ty>)?| $is_bit_valid:expr)? - ) => {}; - ( - $(#[$attr:meta])* - $trait:ident $(, $traits:ident)* for $ty:ty [$inner:ty] $(; |$candidate:ident $(: MaybeAligned<$ref_repr:ty>)? $(: Maybe<$ptr_repr:ty>)?| $is_bit_valid:expr)? + $trait:ident for $ty:ty [$inner:ty] ) => { - impl_for_transparent_wrapper!( - $(#[$attr])* - $($traits),* for $ty [$inner] $(; |$candidate $(: MaybeAligned<$ref_repr>)? $(: Maybe<$ptr_repr>)?| $is_bit_valid:expr)? - ); - - $(#[$attr])* - #[allow(non_local_definitions)] - // SAFETY: - // - We explicitly add a `$tyvar: $trait` bound (regardless of what - // bounds the caller has provided). - // - Inside of `only_derive_is_allowed_to_implement_this_trait`, `f` is - // generic over the any `I: Invariants`. - // - `f` can only compile if its internal call to - // `is_transparent_wrapper` compiles. - // - // The definition of `is_transparent_wrapper` is generated by - // each `@is_transparent_wrapper` macro arm. Each arm is parameterized - // by `$trait`, and emits bounds which are sufficient to ensure that - // this is a sound implementation of `$trait for W` *so long as* `T: - // $trait`. In `f`, we call `is_transparent_wrapper`, - // and so if this code compiles, that guarantees that `$ty` satisfies - // the same bounds so long as `$inner: $trait`. Thus, so long as the - // bounds emitted by the `@is_transparent_wrapper` arm are sound, then - // this entire impl is sound. - // - // Each `@is_transparent_wrapper` arm contains its own safety comment - // which explains why its bounds are sound. - unsafe impl $trait for $ty { - #[allow(dead_code, clippy::missing_inline_in_public_items)] - fn only_derive_is_allowed_to_implement_this_trait() { - use crate::{pointer::invariant::Invariants, util::*}; - - impl_for_transparent_wrapper!(@is_transparent_wrapper $trait); - - fn f() { - is_transparent_wrapper::(); - } - } - - impl_for_transparent_wrapper!(@is_bit_valid $trait for $ty); - } + impl_for_transparent_wrapper!($(#[$attr])* => $trait for $ty [$inner]); }; (@is_transparent_wrapper NoCell) => { // SAFETY: `W: TransparentWrapper`