diff --git a/src/lib.rs b/src/lib.rs index 47a551d..4a85aac 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,5 @@ #![deny(missing_docs)] -#![cfg_attr(feature = "oibit", feature(optin_builtin_traits))] +#![cfg_attr(feature = "oibit", feature(auto_traits, negative_impls))] //! A safe approach to using `#[repr(packed)]` data. //! @@ -9,11 +9,47 @@ use std::mem::{transmute, uninitialized, forget, align_of, size_of}; use std::ptr::write; use std::marker::PhantomData; -/// A marker trait indicating that a type has an alignment of `1`. -/// -/// In general, only applies to `()`, `bool`, `i8`, `u8`, and any types that -/// contain only members of these types. -pub unsafe trait Unaligned { } +macro_rules! define_marker_trait_unaligned { + ([$($auto:ident)?] $($impl:item)*) => { + /// A marker trait indicating that a type has an alignment of `1`. + /// + /// In general, only applies to `()`, `bool`, `i8`, `u8`, and any types that + /// contain only members of these types. + pub unsafe $($auto)? trait Unaligned { } + + $($impl)* + } +} + +#[cfg(not(feature = "oibit"))] +define_marker_trait_unaligned! { [] + unsafe impl Unaligned for () { } + unsafe impl Unaligned for i8 { } + unsafe impl Unaligned for u8 { } + unsafe impl Unaligned for bool { } +} + +#[cfg(feature = "oibit")] +define_marker_trait_unaligned! { [auto] + // All primitives except the packed ones listed above + impl !Unaligned for char { } + impl !Unaligned for f32 { } + impl !Unaligned for f64 { } + impl !Unaligned for i16 { } + impl !Unaligned for u16 { } + impl !Unaligned for i32 { } + impl !Unaligned for u32 { } + impl !Unaligned for i64 { } + impl !Unaligned for u64 { } + impl !Unaligned for isize { } + impl !Unaligned for usize { } + impl !Unaligned for *const T { } + impl !Unaligned for *mut T { } + impl<'a, T> !Unaligned for &'a T { } + impl<'a, T> !Unaligned for &'a mut T { } +} + +unsafe impl Unaligned for PhantomData { } /// A type alias that represents the unaligned type of `T`. pub type Un = ::Unaligned; @@ -134,42 +170,6 @@ pub unsafe trait Packed: Unaligned { fn __assert_unaligned() { } } -#[cfg(feature = "oibit")] -mod impls { - use super::Unaligned; - - unsafe impl Unaligned for .. { } - - // All primitives except the packed ones listed below - impl !Unaligned for char { } - impl !Unaligned for f32 { } - impl !Unaligned for f64 { } - impl !Unaligned for i16 { } - impl !Unaligned for u16 { } - impl !Unaligned for i32 { } - impl !Unaligned for u32 { } - impl !Unaligned for i64 { } - impl !Unaligned for u64 { } - impl !Unaligned for isize { } - impl !Unaligned for usize { } - impl !Unaligned for *const T { } - impl !Unaligned for *mut T { } - impl<'a, T> !Unaligned for &'a T { } - impl<'a, T> !Unaligned for &'a mut T { } -} - -#[cfg(not(feature = "oibit"))] -mod impls { - use super::Unaligned; - - unsafe impl Unaligned for () { } - unsafe impl Unaligned for i8 { } - unsafe impl Unaligned for u8 { } - unsafe impl Unaligned for bool { } -} - -unsafe impl Unaligned for PhantomData { } - macro_rules! aligned_assert { ($t:ident) => { unsafe fn __assert_unaligned() {