Skip to content

Commit

Permalink
[wip] Support derive(KnownLayout) on DSTs
Browse files Browse the repository at this point in the history
Makes progress towards #29.
  • Loading branch information
jswrenn committed Nov 27, 2023
1 parent eb922ca commit 5345efa
Show file tree
Hide file tree
Showing 3 changed files with 312 additions and 91 deletions.
40 changes: 35 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,12 @@ pub enum _CastType {
}

impl DstLayout {
/// The minimum possible alignment of a type.
const MIN_ALIGN: NonZeroUsize = match NonZeroUsize::new(1) {
Some(min_align) => min_align,
None => unreachable!(),
};

/// The maximum theoretic possible alignment of a type.
///
/// For compatibility with future Rust versions, this is defined as the
Expand All @@ -419,6 +425,30 @@ impl DstLayout {
None => unreachable!(),
};

/// Constructs a `DstLayout` for a zero-sized type with `repr_align`
/// alignment (or 1). If `repr_align` is provided, then it must be a power
/// of two.
///
/// # Panics
///
/// This function panics if the supplied `repr_align` is not a power of two.
///
/// # Safety
///
/// Unsafe code may assume that the contract of this function is satisfied.
#[doc(hidden)]
#[inline]
pub const fn new_zst(repr_align: Option<NonZeroUsize>) -> DstLayout {
let align = match repr_align {
Some(align) => align,
None => Self::MIN_ALIGN,
};

assert!(align.is_power_of_two());

DstLayout { _align: align, _size_info: SizeInfo::Sized { _size: 0 } }
}

/// Constructs a `DstLayout` which describes `T`.
///
/// # Safety
Expand Down Expand Up @@ -490,8 +520,8 @@ impl DstLayout {
/// We make no guarantees to the behavior of this method if these fragments
/// cannot appear in a valid Rust type (e.g., the concatenation of the
/// layouts would lead to a size larger than `isize::MAX`).
#[allow(dead_code)]
pub(crate) const fn extend(self, field: DstLayout, repr_packed: Option<NonZeroUsize>) -> Self {
#[doc(hidden)]
pub const fn extend(self, field: DstLayout, repr_packed: Option<NonZeroUsize>) -> Self {
use util::{core_layout::_padding_needed_for, max, min};

// If `repr_packed` is `None`, there are no alignment constraints, and
Expand Down Expand Up @@ -628,8 +658,8 @@ impl DstLayout {
/// We make no guarantees to the behavior of this method if `self` cannot
/// appear in a valid Rust type (e.g., because the addition of trailing
/// padding would lead to a size larger than `isize::MAX`).
#[allow(dead_code)]
pub(crate) const fn pad_to_align(self) -> Self {
#[doc(hidden)]
pub const fn pad_to_align(self) -> Self {
use util::core_layout::_padding_needed_for;

let size_info = match self._size_info {
Expand Down Expand Up @@ -6024,7 +6054,7 @@ mod tests {
assert_impls!(Wrapping<NotZerocopy>: KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);

assert_impls!(Unalign<u8>: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned);
assert_impls!(Unalign<NotZerocopy>: KnownLayout, Unaligned, !FromZeroes, !FromBytes, !AsBytes);
assert_impls!(Unalign<NotZerocopy>: Unaligned, !KnownLayout, !FromZeroes, !FromBytes, !AsBytes);

assert_impls!([u8]: KnownLayout, FromZeroes, FromBytes, AsBytes, Unaligned);
assert_impls!([NotZerocopy]: !KnownLayout, !FromZeroes, !FromBytes, !AsBytes, !Unaligned);
Expand Down
Loading

0 comments on commit 5345efa

Please sign in to comment.