zerocopy/util/
mod.rs

1// Copyright 2023 The Fuchsia Authors
2//
3// Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4// <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5// license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6// This file may not be copied, modified, or distributed except according to
7// those terms.
8
9#[macro_use]
10mod macros;
11
12#[doc(hidden)]
13pub mod macro_util;
14
15use core::{
16    cell::UnsafeCell,
17    marker::PhantomData,
18    mem::{self, ManuallyDrop, MaybeUninit},
19    num::{NonZeroUsize, Wrapping},
20    ptr::NonNull,
21};
22
23use crate::{
24    error::AlignmentError,
25    pointer::invariant::{self, Invariants},
26    Unalign,
27};
28
29/// A type which has the same layout as the type it wraps.
30///
31/// # Safety
32///
33/// `T: TransparentWrapper` implies that `T` has the same size as [`T::Inner`].
34/// Further, `T: TransparentWrapper<I>` implies that:
35/// - If `T::UnsafeCellVariance = Covariant`, then `T` has `UnsafeCell`s
36///   covering the same byte ranges as `T::Inner`.
37/// - If a `T` pointer satisfies the alignment invariant `I::Alignment`, then
38///   that same pointer, cast to `T::Inner`, satisfies the alignment invariant
39///   `<T::AlignmentVariance as AlignmentVariance<I::Alignment>>::Applied`.
40/// - If a `T` pointer satisfies the validity invariant `I::Validity`, then that
41///   same pointer, cast to `T::Inner`, satisfies the validity invariant
42///   `<T::ValidityVariance as ValidityVariance<I::Validity>>::Applied`.
43///
44/// [`T::Inner`]: TransparentWrapper::Inner
45/// [`UnsafeCell`]: core::cell::UnsafeCell
46/// [`T::AlignmentVariance`]: TransparentWrapper::AlignmentVariance
47/// [`T::ValidityVariance`]: TransparentWrapper::ValidityVariance
48#[doc(hidden)]
49pub unsafe trait TransparentWrapper<I: Invariants> {
50    type Inner: ?Sized;
51
52    type UnsafeCellVariance;
53    type AlignmentVariance: AlignmentVariance<I::Alignment>;
54    type ValidityVariance: ValidityVariance<I::Validity>;
55
56    /// Casts a wrapper pointer to an inner pointer.
57    ///
58    /// # Safety
59    ///
60    /// The resulting pointer has the same address and provenance as `ptr`, and
61    /// addresses the same number of bytes.
62    fn cast_into_inner(ptr: *mut Self) -> *mut Self::Inner;
63
64    /// Casts an inner pointer to a wrapper pointer.
65    ///
66    /// # Safety
67    ///
68    /// The resulting pointer has the same address and provenance as `ptr`, and
69    /// addresses the same number of bytes.
70    fn cast_from_inner(ptr: *mut Self::Inner) -> *mut Self;
71}
72
73#[allow(unreachable_pub)]
74#[doc(hidden)]
75pub trait AlignmentVariance<I: invariant::Alignment> {
76    type Applied: invariant::Alignment;
77}
78
79#[allow(unreachable_pub)]
80#[doc(hidden)]
81pub trait ValidityVariance<I: invariant::Validity> {
82    type Applied: invariant::Validity;
83}
84
85#[doc(hidden)]
86#[allow(missing_copy_implementations, missing_debug_implementations)]
87pub enum Covariant {}
88
89impl<I: invariant::Alignment> AlignmentVariance<I> for Covariant {
90    type Applied = I;
91}
92
93impl<I: invariant::Validity> ValidityVariance<I> for Covariant {
94    type Applied = I;
95}
96
97#[doc(hidden)]
98#[allow(missing_copy_implementations, missing_debug_implementations)]
99pub enum Invariant {}
100
101impl<I: invariant::Alignment> AlignmentVariance<I> for Invariant {
102    type Applied = invariant::Any;
103}
104
105impl<I: invariant::Validity> ValidityVariance<I> for Invariant {
106    type Applied = invariant::Any;
107}
108
109// SAFETY:
110// - Per [1], `MaybeUninit<T>` has the same size as `T`.
111// - See inline comments for other safety justifications.
112//
113// [1] Per https://doc.rust-lang.org/1.81.0/std/mem/union.MaybeUninit.html#layout-1:
114//
115//   `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as
116//   `T`
117unsafe impl<T, I: Invariants> TransparentWrapper<I> for MaybeUninit<T> {
118    type Inner = T;
119
120    // SAFETY: `MaybeUninit<T>` has `UnsafeCell`s covering the same byte ranges
121    // as `Inner = T`. This is not explicitly documented, but it can be
122    // inferred. Per [1] in the preceding safety comment, `MaybeUninit<T>` has
123    // the same size as `T`. Further, note the signature of
124    // `MaybeUninit::assume_init_ref` [2]:
125    //
126    //   pub unsafe fn assume_init_ref(&self) -> &T
127    //
128    // If the argument `&MaybeUninit<T>` and the returned `&T` had `UnsafeCell`s
129    // at different offsets, this would be unsound. Its existence is proof that
130    // this is not the case.
131    //
132    // [2] https://doc.rust-lang.org/1.81.0/std/mem/union.MaybeUninit.html#method.assume_init_ref
133    type UnsafeCellVariance = Covariant;
134    // SAFETY: Per [1], `MaybeUninit<T>` has the same layout as `T`, and thus
135    // has the same alignment as `T`.
136    //
137    // [1] Per https://doc.rust-lang.org/std/mem/union.MaybeUninit.html#layout-1:
138    //
139    //   `MaybeUninit<T>` is guaranteed to have the same size, alignment, and
140    //   ABI as `T`.
141    type AlignmentVariance = Covariant;
142    // SAFETY: `MaybeUninit` has no validity invariants. Thus, a valid
143    // `MaybeUninit<T>` is not necessarily a valid `T`.
144    type ValidityVariance = Invariant;
145
146    #[inline(always)]
147    fn cast_into_inner(ptr: *mut MaybeUninit<T>) -> *mut T {
148        // SAFETY: Per [1] (from comment above), `MaybeUninit<T>` has the same
149        // layout as `T`. Thus, this cast preserves size.
150        //
151        // This cast trivially preserves provenance.
152        ptr.cast::<T>()
153    }
154
155    #[inline(always)]
156    fn cast_from_inner(ptr: *mut T) -> *mut MaybeUninit<T> {
157        // SAFETY: Per [1] (from comment above), `MaybeUninit<T>` has the same
158        // layout as `T`. Thus, this cast preserves size.
159        //
160        // This cast trivially preserves provenance.
161        ptr.cast::<MaybeUninit<T>>()
162    }
163}
164
165// SAFETY:
166// - Per [1], `ManuallyDrop<T>` has the same size as `T`.
167// - See inline comments for other safety justifications.
168//
169// [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
170//
171//   `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
172//   `T`
173unsafe impl<T: ?Sized, I: Invariants> TransparentWrapper<I> for ManuallyDrop<T> {
174    type Inner = T;
175
176    // SAFETY: Per [1], `ManuallyDrop<T>` has `UnsafeCell`s covering the same
177    // byte ranges as `Inner = T`.
178    //
179    // [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
180    //
181    //   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
182    //   validity as `T`, and is subject to the same layout optimizations as
183    //   `T`. As a consequence, it has no effect on the assumptions that the
184    //   compiler makes about its contents.
185    type UnsafeCellVariance = Covariant;
186    // SAFETY: Per [1], `ManuallyDrop<T>` has the same layout as `T`, and thus
187    // has the same alignment as `T`.
188    //
189    // [1] Per https://doc.rust-lang.org/nightly/core/mem/struct.ManuallyDrop.html:
190    //
191    //   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
192    //   validity as `T`
193    type AlignmentVariance = Covariant;
194
195    // SAFETY: Per [1] (from comment above), `ManuallyDrop<T>` has the same bit
196    // validity as `T`.
197    type ValidityVariance = Covariant;
198
199    #[inline(always)]
200    fn cast_into_inner(ptr: *mut ManuallyDrop<T>) -> *mut T {
201        // SAFETY: Per [1] (from comment above), `ManuallyDrop<T>` has the same
202        // layout as `T`. Thus, this cast preserves size even if `T` is unsized.
203        //
204        // This cast trivially preserves provenance.
205        #[allow(clippy::as_conversions)]
206        return ptr as *mut T;
207    }
208
209    #[inline(always)]
210    fn cast_from_inner(ptr: *mut T) -> *mut ManuallyDrop<T> {
211        // SAFETY: Per [1] (from comment above), `ManuallyDrop<T>` has the same
212        // layout as `T`. Thus, this cast preserves size even if `T` is unsized.
213        //
214        // This cast trivially preserves provenance.
215        #[allow(clippy::as_conversions)]
216        return ptr as *mut ManuallyDrop<T>;
217    }
218}
219
220// SAFETY:
221// - Per [1], `Wrapping<T>` has the same size as `T`.
222// - See inline comments for other safety justifications.
223//
224// [1] Per https://doc.rust-lang.org/1.81.0/std/num/struct.Wrapping.html#layout-1:
225//
226//   `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
227unsafe impl<T, I: Invariants> TransparentWrapper<I> for Wrapping<T> {
228    type Inner = T;
229
230    // SAFETY: Per [1], `Wrapping<T>` has the same layout as `T`. Since its
231    // single field (of type `T`) is public, it would be a breaking change to
232    // add or remove fields. Thus, we know that `Wrapping<T>` contains a `T` (as
233    // opposed to just having the same size and alignment as `T`) with no pre-
234    // or post-padding. Thus, `Wrapping<T>` must have `UnsafeCell`s covering the
235    // same byte ranges as `Inner = T`.
236    //
237    // [1] Per https://doc.rust-lang.org/1.81.0/std/num/struct.Wrapping.html#layout-1:
238    //
239    //   `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
240    type UnsafeCellVariance = Covariant;
241    // SAFETY: Per [1], `Wrapping<T>` has the same layout as `T`, and thus has
242    // the same alignment as `T`.
243    //
244    // [1] Per https://doc.rust-lang.org/core/num/struct.Wrapping.html#layout-1:
245    //
246    //   `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
247    type AlignmentVariance = Covariant;
248
249    // SAFETY: `Wrapping<T>` has only one field, which is `pub` [2]. We are also
250    // guaranteed per [1] (from the comment above) that `Wrapping<T>` has the
251    // same layout as `T`. The only way for both of these to be true
252    // simultaneously is for `Wrapping<T>` to have the same bit validity as `T`.
253    // In particular, in order to change the bit validity, one of the following
254    // would need to happen:
255    // - `Wrapping` could change its `repr`, but this would violate the layout
256    //   guarantee.
257    // - `Wrapping` could add or change its fields, but this would be a
258    //   stability-breaking change.
259    //
260    // [2] https://doc.rust-lang.org/core/num/struct.Wrapping.html
261    type ValidityVariance = Covariant;
262
263    #[inline(always)]
264    fn cast_into_inner(ptr: *mut Wrapping<T>) -> *mut T {
265        // SAFETY: Per [1] (from comment above), `Wrapping<T>` has the same
266        // layout as `T`. Thus, this cast preserves size.
267        //
268        // This cast trivially preserves provenance.
269        ptr.cast::<T>()
270    }
271
272    #[inline(always)]
273    fn cast_from_inner(ptr: *mut T) -> *mut Wrapping<T> {
274        // SAFETY: Per [1] (from comment above), `Wrapping<T>` has the same
275        // layout as `T`. Thus, this cast preserves size.
276        //
277        // This cast trivially preserves provenance.
278        ptr.cast::<Wrapping<T>>()
279    }
280}
281
282// SAFETY:
283// - Per [1], `UnsafeCell<T>` has the same size as `T`.
284// - See inline comments for other safety justifications.
285//
286// [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
287//
288//   `UnsafeCell<T>` has the same in-memory representation as its inner type
289//   `T`.
290unsafe impl<T: ?Sized, I: Invariants> TransparentWrapper<I> for UnsafeCell<T> {
291    type Inner = T;
292
293    // SAFETY: Since we set this to `Invariant`, we make no safety claims.
294    type UnsafeCellVariance = Invariant;
295
296    // SAFETY: Per [1] (from comment on impl), `Unalign<T>` has the same
297    // representation as `T`, and thus has the same alignment as `T`.
298    type AlignmentVariance = Covariant;
299
300    // SAFETY: Per [1], `Unalign<T>` has the same bit validity as `T`.
301    // Technically the term "representation" doesn't guarantee this, but the
302    // subsequent sentence in the documentation makes it clear that this is the
303    // intention.
304    //
305    // [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
306    //
307    //   `UnsafeCell<T>` has the same in-memory representation as its inner type
308    //   `T`. A consequence of this guarantee is that it is possible to convert
309    //   between `T` and `UnsafeCell<T>`.
310    type ValidityVariance = Covariant;
311
312    #[inline(always)]
313    fn cast_into_inner(ptr: *mut UnsafeCell<T>) -> *mut T {
314        // SAFETY: Per [1] (from comment above), `UnsafeCell<T>` has the same
315        // representation as `T`. Thus, this cast preserves size.
316        //
317        // This cast trivially preserves provenance.
318        #[allow(clippy::as_conversions)]
319        return ptr as *mut T;
320    }
321
322    #[inline(always)]
323    fn cast_from_inner(ptr: *mut T) -> *mut UnsafeCell<T> {
324        // SAFETY: Per [1] (from comment above), `UnsafeCell<T>` has the same
325        // representation as `T`. Thus, this cast preserves size.
326        //
327        // This cast trivially preserves provenance.
328        #[allow(clippy::as_conversions)]
329        return ptr as *mut UnsafeCell<T>;
330    }
331}
332
333// SAFETY: `Unalign<T>` promises to have the same size as `T`.
334//
335// See inline comments for other safety justifications.
336unsafe impl<T, I: Invariants> TransparentWrapper<I> for Unalign<T> {
337    type Inner = T;
338
339    // SAFETY: `Unalign<T>` promises to have `UnsafeCell`s covering the same
340    // byte ranges as `Inner = T`.
341    type UnsafeCellVariance = Covariant;
342
343    // SAFETY: Since `Unalign<T>` promises to have alignment 1 regardless of
344    // `T`'s alignment. Thus, an aligned pointer to `Unalign<T>` is not
345    // necessarily an aligned pointer to `T`.
346    type AlignmentVariance = Invariant;
347
348    // SAFETY: `Unalign<T>` promises to have the same validity as `T`.
349    type ValidityVariance = Covariant;
350
351    #[inline(always)]
352    fn cast_into_inner(ptr: *mut Unalign<T>) -> *mut T {
353        // SAFETY: Per the safety comment on the impl block, `Unalign<T>` has
354        // the size as `T`. Thus, this cast preserves size.
355        //
356        // This cast trivially preserves provenance.
357        ptr.cast::<T>()
358    }
359
360    #[inline(always)]
361    fn cast_from_inner(ptr: *mut T) -> *mut Unalign<T> {
362        // SAFETY: Per the safety comment on the impl block, `Unalign<T>` has
363        // the size as `T`. Thus, this cast preserves size.
364        //
365        // This cast trivially preserves provenance.
366        ptr.cast::<Unalign<T>>()
367    }
368}
369
370/// Implements `TransparentWrapper` for an atomic type.
371///
372/// # Safety
373///
374/// The caller promises that `$atomic` is an atomic type whose natie equivalent
375/// is `$native`.
376#[cfg(all(
377    zerocopy_target_has_atomics_1_60_0,
378    any(
379        target_has_atomic = "8",
380        target_has_atomic = "16",
381        target_has_atomic = "32",
382        target_has_atomic = "64",
383        target_has_atomic = "ptr"
384    )
385))]
386macro_rules! unsafe_impl_transparent_wrapper_for_atomic {
387    ($(#[$attr:meta])* $(,)?) => {};
388    ($(#[$attr:meta])* $atomic:ty [$native:ty], $($atomics:ty [$natives:ty]),* $(,)?) => {
389        $(#[$attr])*
390        // SAFETY: See safety comment in next match arm.
391        unsafe impl<I: crate::invariant::Invariants> crate::util::TransparentWrapper<I> for $atomic {
392            unsafe_impl_transparent_wrapper_for_atomic!(@inner $atomic [$native]);
393        }
394        unsafe_impl_transparent_wrapper_for_atomic!($(#[$attr])* $($atomics [$natives],)*);
395    };
396    ($(#[$attr:meta])* $tyvar:ident => $atomic:ty [$native:ty]) => {
397        // We implement for `$atomic` and set `Inner = $native`. The caller has
398        // promised that `$atomic` and `$native` are an atomic type and its
399        // native counterpart, respectively. Per [1], `$atomic` and `$native`
400        // have the same size.
401        //
402        // [1] Per (for example) https://doc.rust-lang.org/1.81.0/std/sync/atomic/struct.AtomicU64.html:
403        //
404        //   This type has the same size and bit validity as the underlying
405        //   integer type
406        $(#[$attr])*
407        unsafe impl<$tyvar, I: crate::invariant::Invariants> crate::util::TransparentWrapper<I> for $atomic {
408            unsafe_impl_transparent_wrapper_for_atomic!(@inner $atomic [$native]);
409        }
410    };
411    (@inner $atomic:ty [$native:ty]) => {
412        type Inner = UnsafeCell<$native>;
413
414        // SAFETY: It is "obvious" that each atomic type contains a single
415        // `UnsafeCell` that covers all bytes of the type, but we can also prove
416        // it:
417        // - Since `$atomic` provides an API which permits loading and storing
418        //   values of type `$native` via a `&self` (shared) reference, *some*
419        //   interior mutation must be happening, and interior mutation can only
420        //   happen via `UnsafeCell`. Further, there must be enough bytes in
421        //   `$atomic` covered by an `UnsafeCell` to hold every possible value
422        //   of `$native`.
423        // - Per [1], `$atomic` has the same size as `$native`. This on its own
424        //   isn't enough: it would still be possible for `$atomic` to store
425        //   `$native` using a compact representation (for `$native` types for
426        //   which some bit patterns are illegal). However, this is ruled out by
427        //   the fact that `$atomic` has the same bit validity as `$native` [1].
428        //   Thus, we can conclude that every byte of `$atomic` must be covered
429        //   by an `UnsafeCell`.
430        //
431        // Thus, every byte of `$atomic` is covered by an `UnsafeCell`, and we
432        // set `type Inner = UnsafeCell<$native>`. Thus, `Self` and
433        // `Self::Inner` have `UnsafeCell`s covering the same byte ranges.
434        //
435        // [1] Per (for example) https://doc.rust-lang.org/1.81.0/std/sync/atomic/struct.AtomicU64.html:
436        //
437        //   This type has the same size and bit validity as the underlying
438        //   integer type
439        type UnsafeCellVariance = crate::util::Covariant;
440
441        // SAFETY: No safety justification is required for an invariant
442        // variance.
443        type AlignmentVariance = crate::util::Invariant;
444
445        // SAFETY: Per [1], all atomic types have the same bit validity as their
446        // native counterparts. The caller has promised that `$atomic` and
447        // `$native` are an atomic type and its native counterpart,
448        // respectively.
449        //
450        // [1] Per (for example) https://doc.rust-lang.org/1.81.0/std/sync/atomic/struct.AtomicU64.html:
451        //
452        //   This type has the same size and bit validity as the underlying
453        //   integer type
454        type ValidityVariance = crate::util::Covariant;
455
456        #[inline(always)]
457        fn cast_into_inner(ptr: *mut $atomic) -> *mut UnsafeCell<$native> {
458            // SAFETY: Per [1] (from comment on impl block), `$atomic` has the
459            // same size as `$native`. Thus, this cast preserves size.
460            //
461            // This cast trivially preserves provenance.
462            ptr.cast::<UnsafeCell<$native>>()
463        }
464
465        #[inline(always)]
466        fn cast_from_inner(ptr: *mut UnsafeCell<$native>) -> *mut $atomic {
467            // SAFETY: Per [1] (from comment on impl block), `$atomic` has the
468            // same size as `$native`. Thus, this cast preserves size.
469            //
470            // This cast trivially preserves provenance.
471            ptr.cast::<$atomic>()
472        }
473    };
474}
475
476/// Like [`PhantomData`], but [`Send`] and [`Sync`] regardless of whether the
477/// wrapped `T` is.
478pub(crate) struct SendSyncPhantomData<T: ?Sized>(PhantomData<T>);
479
480// SAFETY: `SendSyncPhantomData` does not enable any behavior which isn't sound
481// to be called from multiple threads.
482unsafe impl<T: ?Sized> Send for SendSyncPhantomData<T> {}
483// SAFETY: `SendSyncPhantomData` does not enable any behavior which isn't sound
484// to be called from multiple threads.
485unsafe impl<T: ?Sized> Sync for SendSyncPhantomData<T> {}
486
487impl<T: ?Sized> Default for SendSyncPhantomData<T> {
488    fn default() -> SendSyncPhantomData<T> {
489        SendSyncPhantomData(PhantomData)
490    }
491}
492
493impl<T: ?Sized> PartialEq for SendSyncPhantomData<T> {
494    fn eq(&self, other: &Self) -> bool {
495        self.0.eq(&other.0)
496    }
497}
498
499impl<T: ?Sized> Eq for SendSyncPhantomData<T> {}
500
501pub(crate) trait AsAddress {
502    fn addr(self) -> usize;
503}
504
505impl<T: ?Sized> AsAddress for &T {
506    #[inline(always)]
507    fn addr(self) -> usize {
508        let ptr: *const T = self;
509        AsAddress::addr(ptr)
510    }
511}
512
513impl<T: ?Sized> AsAddress for &mut T {
514    #[inline(always)]
515    fn addr(self) -> usize {
516        let ptr: *const T = self;
517        AsAddress::addr(ptr)
518    }
519}
520
521impl<T: ?Sized> AsAddress for NonNull<T> {
522    #[inline(always)]
523    fn addr(self) -> usize {
524        AsAddress::addr(self.as_ptr())
525    }
526}
527
528impl<T: ?Sized> AsAddress for *const T {
529    #[inline(always)]
530    fn addr(self) -> usize {
531        // TODO(#181), TODO(https://github.com/rust-lang/rust/issues/95228): Use
532        // `.addr()` instead of `as usize` once it's stable, and get rid of this
533        // `allow`. Currently, `as usize` is the only way to accomplish this.
534        #[allow(clippy::as_conversions)]
535        #[cfg_attr(
536            __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS,
537            allow(lossy_provenance_casts)
538        )]
539        return self.cast::<()>() as usize;
540    }
541}
542
543impl<T: ?Sized> AsAddress for *mut T {
544    #[inline(always)]
545    fn addr(self) -> usize {
546        let ptr: *const T = self;
547        AsAddress::addr(ptr)
548    }
549}
550
551/// Validates that `t` is aligned to `align_of::<U>()`.
552#[inline(always)]
553pub(crate) fn validate_aligned_to<T: AsAddress, U>(t: T) -> Result<(), AlignmentError<(), U>> {
554    // `mem::align_of::<U>()` is guaranteed to return a non-zero value, which in
555    // turn guarantees that this mod operation will not panic.
556    #[allow(clippy::arithmetic_side_effects)]
557    let remainder = t.addr() % mem::align_of::<U>();
558    if remainder == 0 {
559        Ok(())
560    } else {
561        // SAFETY: We just confirmed that `t.addr() % align_of::<U>() != 0`.
562        // That's only possible if `align_of::<U>() > 1`.
563        Err(unsafe { AlignmentError::new_unchecked(()) })
564    }
565}
566
567/// Returns the bytes needed to pad `len` to the next multiple of `align`.
568///
569/// This function assumes that align is a power of two; there are no guarantees
570/// on the answer it gives if this is not the case.
571pub(crate) const fn padding_needed_for(len: usize, align: NonZeroUsize) -> usize {
572    // Abstractly, we want to compute:
573    //   align - (len % align).
574    // Handling the case where len%align is 0.
575    // Because align is a power of two, len % align = len & (align-1).
576    // Guaranteed not to underflow as align is nonzero.
577    #[allow(clippy::arithmetic_side_effects)]
578    let mask = align.get() - 1;
579
580    // To efficiently subtract this value from align, we can use the bitwise complement.
581    // Note that ((!len) & (align-1)) gives us a number that with (len &
582    // (align-1)) sums to align-1. So subtracting 1 from x before taking the
583    // complement subtracts `len` from `align`. Some quick inspection of
584    // cases shows that this also handles the case where `len % align = 0`
585    // correctly too: len-1 % align then equals align-1, so the complement mod
586    // align will be 0, as desired.
587    //
588    // The following reasoning can be verified quickly by an SMT solver
589    // supporting the theory of bitvectors:
590    // ```smtlib
591    // ; Naive implementation of padding
592    // (define-fun padding1 (
593    //     (len (_ BitVec 32))
594    //     (align (_ BitVec 32))) (_ BitVec 32)
595    //    (ite
596    //      (= (_ bv0 32) (bvand len (bvsub align (_ bv1 32))))
597    //      (_ bv0 32)
598    //      (bvsub align (bvand len (bvsub align (_ bv1 32))))))
599    //
600    // ; The implementation below
601    // (define-fun padding2 (
602    //     (len (_ BitVec 32))
603    //     (align (_ BitVec 32))) (_ BitVec 32)
604    // (bvand (bvnot (bvsub len (_ bv1 32))) (bvsub align (_ bv1 32))))
605    //
606    // (define-fun is-power-of-two ((x (_ BitVec 32))) Bool
607    //   (= (_ bv0 32) (bvand x (bvsub x (_ bv1 32)))))
608    //
609    // (declare-const len (_ BitVec 32))
610    // (declare-const align (_ BitVec 32))
611    // ; Search for a case where align is a power of two and padding2 disagrees with padding1
612    // (assert (and (is-power-of-two align)
613    //              (not (= (padding1 len align) (padding2 len align)))))
614    // (simplify (padding1 (_ bv300 32) (_ bv32 32))) ; 20
615    // (simplify (padding2 (_ bv300 32) (_ bv32 32))) ; 20
616    // (simplify (padding1 (_ bv322 32) (_ bv32 32))) ; 30
617    // (simplify (padding2 (_ bv322 32) (_ bv32 32))) ; 30
618    // (simplify (padding1 (_ bv8 32) (_ bv8 32)))    ; 0
619    // (simplify (padding2 (_ bv8 32) (_ bv8 32)))    ; 0
620    // (check-sat) ; unsat, also works for 64-bit bitvectors
621    // ```
622    !(len.wrapping_sub(1)) & mask
623}
624
625/// Rounds `n` down to the largest value `m` such that `m <= n` and `m % align
626/// == 0`.
627///
628/// # Panics
629///
630/// May panic if `align` is not a power of two. Even if it doesn't panic in this
631/// case, it will produce nonsense results.
632#[inline(always)]
633pub(crate) const fn round_down_to_next_multiple_of_alignment(
634    n: usize,
635    align: NonZeroUsize,
636) -> usize {
637    let align = align.get();
638    #[cfg(zerocopy_panic_in_const_and_vec_try_reserve_1_57_0)]
639    debug_assert!(align.is_power_of_two());
640
641    // Subtraction can't underflow because `align.get() >= 1`.
642    #[allow(clippy::arithmetic_side_effects)]
643    let mask = !(align - 1);
644    n & mask
645}
646
647pub(crate) const fn max(a: NonZeroUsize, b: NonZeroUsize) -> NonZeroUsize {
648    if a.get() < b.get() {
649        b
650    } else {
651        a
652    }
653}
654
655pub(crate) const fn min(a: NonZeroUsize, b: NonZeroUsize) -> NonZeroUsize {
656    if a.get() > b.get() {
657        b
658    } else {
659        a
660    }
661}
662
663/// Copies `src` into the prefix of `dst`.
664///
665/// # Safety
666///
667/// The caller guarantees that `src.len() <= dst.len()`.
668#[inline(always)]
669pub(crate) unsafe fn copy_unchecked(src: &[u8], dst: &mut [u8]) {
670    debug_assert!(src.len() <= dst.len());
671    // SAFETY: This invocation satisfies the safety contract of
672    // copy_nonoverlapping [1]:
673    // - `src.as_ptr()` is trivially valid for reads of `src.len()` bytes
674    // - `dst.as_ptr()` is valid for writes of `src.len()` bytes, because the
675    //   caller has promised that `src.len() <= dst.len()`
676    // - `src` and `dst` are, trivially, properly aligned
677    // - the region of memory beginning at `src` with a size of `src.len()`
678    //   bytes does not overlap with the region of memory beginning at `dst`
679    //   with the same size, because `dst` is derived from an exclusive
680    //   reference.
681    unsafe {
682        core::ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len());
683    };
684}
685
686/// Unsafely transmutes the given `src` into a type `Dst`.
687///
688/// # Safety
689///
690/// The value `src` must be a valid instance of `Dst`.
691#[inline(always)]
692pub(crate) const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst {
693    static_assert!(Src, Dst => core::mem::size_of::<Src>() == core::mem::size_of::<Dst>());
694
695    #[repr(C)]
696    union Transmute<Src, Dst> {
697        src: ManuallyDrop<Src>,
698        dst: ManuallyDrop<Dst>,
699    }
700
701    // SAFETY: Since `Transmute<Src, Dst>` is `#[repr(C)]`, its `src` and `dst`
702    // fields both start at the same offset and the types of those fields are
703    // transparent wrappers around `Src` and `Dst` [1]. Consequently,
704    // initializng `Transmute` with with `src` and then reading out `dst` is
705    // equivalent to transmuting from `Src` to `Dst` [2]. Transmuting from `src`
706    // to `Dst` is valid because — by contract on the caller — `src` is a valid
707    // instance of `Dst`.
708    //
709    // [1] Per https://doc.rust-lang.org/1.82.0/std/mem/struct.ManuallyDrop.html:
710    //
711    //     `ManuallyDrop<T>` is guaranteed to have the same layout and bit
712    //     validity as `T`, and is subject to the same layout optimizations as
713    //     `T`.
714    //
715    // [2] Per https://doc.rust-lang.org/1.82.0/reference/items/unions.html#reading-and-writing-union-fields:
716    //
717    //     Effectively, writing to and then reading from a union with the C
718    //     representation is analogous to a transmute from the type used for
719    //     writing to the type used for reading.
720    unsafe { ManuallyDrop::into_inner(Transmute { src: ManuallyDrop::new(src) }.dst) }
721}
722
723/// Uses `allocate` to create a `Box<T>`.
724///
725/// # Errors
726///
727/// Returns an error on allocation failure. Allocation failure is guaranteed
728/// never to cause a panic or an abort.
729///
730/// # Safety
731///
732/// `allocate` must be either `alloc::alloc::alloc` or
733/// `alloc::alloc::alloc_zeroed`. The referent of the box returned by `new_box`
734/// has the same bit-validity as the referent of the pointer returned by the
735/// given `allocate` and sufficient size to store `T` with `meta`.
736#[must_use = "has no side effects (other than allocation)"]
737#[cfg(feature = "alloc")]
738#[inline]
739pub(crate) unsafe fn new_box<T>(
740    meta: T::PointerMetadata,
741    allocate: unsafe fn(core::alloc::Layout) -> *mut u8,
742) -> Result<alloc::boxed::Box<T>, crate::error::AllocError>
743where
744    T: ?Sized + crate::KnownLayout,
745{
746    use crate::error::AllocError;
747    use crate::PointerMetadata;
748    use core::alloc::Layout;
749
750    let size = match meta.size_for_metadata(T::LAYOUT) {
751        Some(size) => size,
752        None => return Err(AllocError),
753    };
754
755    let align = T::LAYOUT.align.get();
756    // On stable Rust versions <= 1.64.0, `Layout::from_size_align` has a bug in
757    // which sufficiently-large allocations (those which, when rounded up to the
758    // alignment, overflow `isize`) are not rejected, which can cause undefined
759    // behavior. See #64 for details.
760    //
761    // TODO(#67): Once our MSRV is > 1.64.0, remove this assertion.
762    #[allow(clippy::as_conversions)]
763    let max_alloc = (isize::MAX as usize).saturating_sub(align);
764    if size > max_alloc {
765        return Err(AllocError);
766    }
767
768    // TODO(https://github.com/rust-lang/rust/issues/55724): Use
769    // `Layout::repeat` once it's stabilized.
770    let layout = Layout::from_size_align(size, align).or(Err(AllocError))?;
771
772    let ptr = if layout.size() != 0 {
773        // SAFETY: By contract on the caller, `allocate` is either
774        // `alloc::alloc::alloc` or `alloc::alloc::alloc_zeroed`. The above
775        // check ensures their shared safety precondition: that the supplied
776        // layout is not zero-sized type [1].
777        //
778        // [1] Per https://doc.rust-lang.org/stable/std/alloc/trait.GlobalAlloc.html#tymethod.alloc:
779        //
780        //     This function is unsafe because undefined behavior can result if
781        //     the caller does not ensure that layout has non-zero size.
782        let ptr = unsafe { allocate(layout) };
783        match NonNull::new(ptr) {
784            Some(ptr) => ptr,
785            None => return Err(AllocError),
786        }
787    } else {
788        let align = T::LAYOUT.align.get();
789        // We use `transmute` instead of an `as` cast since Miri (with strict
790        // provenance enabled) notices and complains that an `as` cast creates a
791        // pointer with no provenance. Miri isn't smart enough to realize that
792        // we're only executing this branch when we're constructing a zero-sized
793        // `Box`, which doesn't require provenance.
794        //
795        // SAFETY: any initialized bit sequence is a bit-valid `*mut u8`. All
796        // bits of a `usize` are initialized.
797        #[allow(clippy::useless_transmute)]
798        let dangling = unsafe { mem::transmute::<usize, *mut u8>(align) };
799        // SAFETY: `dangling` is constructed from `T::LAYOUT.align`, which is a
800        // `NonZeroUsize`, which is guaranteed to be non-zero.
801        //
802        // `Box<[T]>` does not allocate when `T` is zero-sized or when `len` is
803        // zero, but it does require a non-null dangling pointer for its
804        // allocation.
805        //
806        // TODO(https://github.com/rust-lang/rust/issues/95228): Use
807        // `std::ptr::without_provenance` once it's stable. That may optimize
808        // better. As written, Rust may assume that this consumes "exposed"
809        // provenance, and thus Rust may have to assume that this may consume
810        // provenance from any pointer whose provenance has been exposed.
811        unsafe { NonNull::new_unchecked(dangling) }
812    };
813
814    let ptr = T::raw_from_ptr_len(ptr, meta);
815
816    // TODO(#429): Add a "SAFETY" comment and remove this `allow`. Make sure to
817    // include a justification that `ptr.as_ptr()` is validly-aligned in the ZST
818    // case (in which we manually construct a dangling pointer) and to justify
819    // why `Box` is safe to drop (it's because `allocate` uses the system
820    // allocator).
821    #[allow(clippy::undocumented_unsafe_blocks)]
822    Ok(unsafe { alloc::boxed::Box::from_raw(ptr.as_ptr()) })
823}
824
825/// Since we support multiple versions of Rust, there are often features which
826/// have been stabilized in the most recent stable release which do not yet
827/// exist (stably) on our MSRV. This module provides polyfills for those
828/// features so that we can write more "modern" code, and just remove the
829/// polyfill once our MSRV supports the corresponding feature. Without this,
830/// we'd have to write worse/more verbose code and leave TODO comments sprinkled
831/// throughout the codebase to update to the new pattern once it's stabilized.
832///
833/// Each trait is imported as `_` at the crate root; each polyfill should "just
834/// work" at usage sites.
835pub(crate) mod polyfills {
836    use core::ptr::{self, NonNull};
837
838    // A polyfill for `NonNull::slice_from_raw_parts` that we can use before our
839    // MSRV is 1.70, when that function was stabilized.
840    //
841    // The `#[allow(unused)]` is necessary because, on sufficiently recent
842    // toolchain versions, `ptr.slice_from_raw_parts()` resolves to the inherent
843    // method rather than to this trait, and so this trait is considered unused.
844    //
845    // TODO(#67): Once our MSRV is 1.70, remove this.
846    #[allow(unused)]
847    pub(crate) trait NonNullExt<T> {
848        fn slice_from_raw_parts(data: Self, len: usize) -> NonNull<[T]>;
849    }
850
851    impl<T> NonNullExt<T> for NonNull<T> {
852        // NOTE on coverage: this will never be tested in nightly since it's a
853        // polyfill for a feature which has been stabilized on our nightly
854        // toolchain.
855        #[cfg_attr(coverage_nightly, coverage(off))]
856        #[inline(always)]
857        fn slice_from_raw_parts(data: Self, len: usize) -> NonNull<[T]> {
858            let ptr = ptr::slice_from_raw_parts_mut(data.as_ptr(), len);
859            // SAFETY: `ptr` is converted from `data`, which is non-null.
860            unsafe { NonNull::new_unchecked(ptr) }
861        }
862    }
863
864    // A polyfill for `Self::unchecked_sub` that we can use until methods like
865    // `usize::unchecked_sub` is stabilized.
866    //
867    // The `#[allow(unused)]` is necessary because, on sufficiently recent
868    // toolchain versions, `ptr.slice_from_raw_parts()` resolves to the inherent
869    // method rather than to this trait, and so this trait is considered unused.
870    //
871    // TODO(#67): Once our MSRV is high enough, remove this.
872    #[allow(unused)]
873    pub(crate) trait NumExt {
874        /// Subtract without checking for underflow.
875        ///
876        /// # Safety
877        ///
878        /// The caller promises that the subtraction will not underflow.
879        unsafe fn unchecked_sub(self, rhs: Self) -> Self;
880    }
881
882    impl NumExt for usize {
883        // NOTE on coverage: this will never be tested in nightly since it's a
884        // polyfill for a feature which has been stabilized on our nightly
885        // toolchain.
886        #[cfg_attr(coverage_nightly, coverage(off))]
887        #[inline(always)]
888        unsafe fn unchecked_sub(self, rhs: usize) -> usize {
889            match self.checked_sub(rhs) {
890                Some(x) => x,
891                None => {
892                    // SAFETY: The caller promises that the subtraction will not
893                    // underflow.
894                    unsafe { core::hint::unreachable_unchecked() }
895                }
896            }
897        }
898    }
899}
900
901#[cfg(test)]
902pub(crate) mod testutil {
903    use crate::*;
904
905    /// A `T` which is aligned to at least `align_of::<A>()`.
906    #[derive(Default)]
907    pub(crate) struct Align<T, A> {
908        pub(crate) t: T,
909        _a: [A; 0],
910    }
911
912    impl<T: Default, A> Align<T, A> {
913        pub(crate) fn set_default(&mut self) {
914            self.t = T::default();
915        }
916    }
917
918    impl<T, A> Align<T, A> {
919        pub(crate) const fn new(t: T) -> Align<T, A> {
920            Align { t, _a: [] }
921        }
922    }
923
924    /// A `T` which is guaranteed not to satisfy `align_of::<A>()`.
925    ///
926    /// It must be the case that `align_of::<T>() < align_of::<A>()` in order
927    /// fot this type to work properly.
928    #[repr(C)]
929    pub(crate) struct ForceUnalign<T: Unaligned, A> {
930        // The outer struct is aligned to `A`, and, thanks to `repr(C)`, `t` is
931        // placed at the minimum offset that guarantees its alignment. If
932        // `align_of::<T>() < align_of::<A>()`, then that offset will be
933        // guaranteed *not* to satisfy `align_of::<A>()`.
934        //
935        // Note that we need `T: Unaligned` in order to guarantee that there is
936        // no padding between `_u` and `t`.
937        _u: u8,
938        pub(crate) t: T,
939        _a: [A; 0],
940    }
941
942    impl<T: Unaligned, A> ForceUnalign<T, A> {
943        pub(crate) fn new(t: T) -> ForceUnalign<T, A> {
944            ForceUnalign { _u: 0, t, _a: [] }
945        }
946    }
947    // A `u64` with alignment 8.
948    //
949    // Though `u64` has alignment 8 on some platforms, it's not guaranteed. By
950    // contrast, `AU64` is guaranteed to have alignment 8 on all platforms.
951    #[derive(
952        KnownLayout,
953        Immutable,
954        FromBytes,
955        IntoBytes,
956        Eq,
957        PartialEq,
958        Ord,
959        PartialOrd,
960        Default,
961        Debug,
962        Copy,
963        Clone,
964    )]
965    #[repr(C, align(8))]
966    pub(crate) struct AU64(pub(crate) u64);
967
968    impl AU64 {
969        // Converts this `AU64` to bytes using this platform's endianness.
970        pub(crate) fn to_bytes(self) -> [u8; 8] {
971            crate::transmute!(self)
972        }
973    }
974
975    impl Display for AU64 {
976        #[cfg_attr(coverage_nightly, coverage(off))]
977        fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
978            Display::fmt(&self.0, f)
979        }
980    }
981
982    #[derive(Immutable, FromBytes, Eq, PartialEq, Ord, PartialOrd, Default, Debug, Copy, Clone)]
983    #[repr(C)]
984    pub(crate) struct Nested<T, U: ?Sized> {
985        _t: T,
986        _u: U,
987    }
988}
989
990#[cfg(test)]
991mod tests {
992    use super::*;
993
994    #[test]
995    fn test_round_down_to_next_multiple_of_alignment() {
996        fn alt_impl(n: usize, align: NonZeroUsize) -> usize {
997            let mul = n / align.get();
998            mul * align.get()
999        }
1000
1001        for align in [1, 2, 4, 8, 16] {
1002            for n in 0..256 {
1003                let align = NonZeroUsize::new(align).unwrap();
1004                let want = alt_impl(n, align);
1005                let got = round_down_to_next_multiple_of_alignment(n, align);
1006                assert_eq!(got, want, "round_down_to_next_multiple_of_alignment({}, {})", n, align);
1007            }
1008        }
1009    }
1010
1011    #[rustversion::since(1.57.0)]
1012    #[test]
1013    #[should_panic]
1014    fn test_round_down_to_next_multiple_of_alignment_zerocopy_panic_in_const_and_vec_try_reserve() {
1015        round_down_to_next_multiple_of_alignment(0, NonZeroUsize::new(3).unwrap());
1016    }
1017}
1018
1019#[cfg(kani)]
1020mod proofs {
1021    use super::*;
1022
1023    #[kani::proof]
1024    fn prove_round_down_to_next_multiple_of_alignment() {
1025        fn model_impl(n: usize, align: NonZeroUsize) -> usize {
1026            assert!(align.get().is_power_of_two());
1027            let mul = n / align.get();
1028            mul * align.get()
1029        }
1030
1031        let align: NonZeroUsize = kani::any();
1032        kani::assume(align.get().is_power_of_two());
1033        let n: usize = kani::any();
1034
1035        let expected = model_impl(n, align);
1036        let actual = round_down_to_next_multiple_of_alignment(n, align);
1037        assert_eq!(expected, actual, "round_down_to_next_multiple_of_alignment({}, {})", n, align);
1038    }
1039
1040    // Restricted to nightly since we use the unstable `usize::next_multiple_of`
1041    // in our model implementation.
1042    #[cfg(__ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS)]
1043    #[kani::proof]
1044    fn prove_padding_needed_for() {
1045        fn model_impl(len: usize, align: NonZeroUsize) -> usize {
1046            let padded = len.next_multiple_of(align.get());
1047            let padding = padded - len;
1048            padding
1049        }
1050
1051        let align: NonZeroUsize = kani::any();
1052        kani::assume(align.get().is_power_of_two());
1053        let len: usize = kani::any();
1054        // Constrain `len` to valid Rust lengths, since our model implementation
1055        // isn't robust to overflow.
1056        kani::assume(len <= isize::MAX as usize);
1057        kani::assume(align.get() < 1 << 29);
1058
1059        let expected = model_impl(len, align);
1060        let actual = padding_needed_for(len, align);
1061        assert_eq!(expected, actual, "padding_needed_for({}, {})", len, align);
1062
1063        let padded_len = actual + len;
1064        assert_eq!(padded_len % align, 0);
1065        assert!(padded_len / align >= len / align);
1066    }
1067}