xref: /linux/rust/zerocopy/src/pointer/transmute.rs (revision c37398010a05055e78cf0c75defb90df06c4e999)
1 // Copyright 2025 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 #![allow(missing_docs)]
10 
11 use core::{
12     cell::{Cell, UnsafeCell},
13     mem::{ManuallyDrop, MaybeUninit},
14     num::Wrapping,
15 };
16 
17 use crate::{
18     pointer::{
19         cast::{self, CastExact, CastSizedExact},
20         invariant::*,
21     },
22     FromBytes, Immutable, IntoBytes, Unalign,
23 };
24 
25 /// Transmutations which are sound to attempt, conditional on validating the bit
26 /// validity of the destination type.
27 ///
28 /// If a `Ptr` transmutation is `TryTransmuteFromPtr`, then it is sound to
29 /// perform that transmutation so long as some additional mechanism is used to
30 /// validate that the referent is bit-valid for the destination type. That
31 /// validation mechanism could be a type bound (such as `TransmuteFrom`) or a
32 /// runtime validity check.
33 ///
34 /// # Safety
35 ///
36 /// ## Post-conditions
37 ///
38 /// Given `Dst: TryTransmuteFromPtr<Src, A, SV, DV, C, _>`, callers may assume
39 /// the following:
40 ///
41 /// Given `src: Ptr<'a, Src, (A, _, SV)>`, if the referent of `src` is
42 /// `DV`-valid for `Dst`, then it is sound to transmute `src` into `dst: Ptr<'a,
43 /// Dst, (A, Unaligned, DV)>` using `C`.
44 ///
45 /// ## Pre-conditions
46 ///
47 /// Given `src: Ptr<Src, (A, _, SV)>` and `dst: Ptr<Dst, (A, Unaligned, DV)>`,
48 /// `Dst: TryTransmuteFromPtr<Src, A, SV, DV, C, _>` is sound if all of the
49 /// following hold:
50 /// - Forwards transmutation: Either of the following hold:
51 ///   - So long as `dst` is active, no mutation of `dst`'s referent is allowed
52 ///     except via `dst` itself
53 ///   - The set of `DV`-valid referents of `dst` is a superset of the set of
54 ///     `SV`-valid referents of `src` (NOTE: this condition effectively bans
55 ///     shrinking or overwriting transmutes, which cannot satisfy this
56 ///     condition)
57 /// - Reverse transmutation: Either of the following hold:
58 ///   - `dst` does not permit mutation of its referent
59 ///   - The set of `DV`-valid referents of `dst` is a subset of the set of
60 ///     `SV`-valid referents of `src` (NOTE: this condition effectively bans
61 ///     shrinking or overwriting transmutes, which cannot satisfy this
62 ///     condition)
63 /// - No safe code, given access to `src` and `dst`, can cause undefined
64 ///   behavior: Any of the following hold:
65 ///   - `A` is `Exclusive`
66 ///   - `Src: Immutable` and `Dst: Immutable`
67 ///   - It is sound for shared code to operate on a `&Src` and `&Dst` which
68 ///     reference the same byte range at the same time
69 ///
70 /// ## Proof
71 ///
72 /// Given:
73 /// - `src: Ptr<'a, Src, (A, _, SV)>`
74 /// - `src`'s referent is `DV`-valid for `Dst`
75 ///
76 /// We are trying to prove that it is sound to perform a cast from `src` to a
77 /// `dst: Ptr<'a, Dst, (A, Unaligned, DV)>` using `C`. We need to prove that
78 /// such a cast does not violate any of `src`'s invariants, and that it
79 /// satisfies all invariants of the destination `Ptr` type.
80 ///
81 /// First, by `C: CastExact`, `src`'s address is unchanged, so it still satisfies
82 /// its alignment. Since `dst`'s alignment is `Unaligned`, it trivially satisfies
83 /// its alignment.
84 ///
85 /// Second, aliasing is either `Exclusive` or `Shared`:
86 /// - If it is `Exclusive`, then both `src` and `dst` satisfy `Exclusive`
87 ///   aliasing trivially: since `src` and `dst` have the same lifetime, `src` is
88 ///   inaccessible so long as `dst` is alive, and no other live `Ptr`s or
89 ///   references may reference the same referent.
90 /// - If it is `Shared`, then either:
91 ///   - `Src: Immutable` and `Dst: Immutable`, and so neither `src` nor `dst`
92 ///     permit interior mutation.
93 ///   - It is explicitly sound for safe code to operate on a `&Src` and a `&Dst`
94 ///     pointing to the same byte range at the same time.
95 ///
96 /// Third, `src`'s validity is satisfied. By invariant, `src`'s referent began
97 /// as an `SV`-valid `Src`. It is guaranteed to remain so, as either of the
98 /// following hold:
99 /// - `dst` does not permit mutation of its referent.
100 /// - The set of `DV`-valid referents of `dst` is a subset of the set of
101 ///   `SV`-valid referents of `src`. Thus, any value written via `dst` is
102 ///   guaranteed to be an `SV`-valid referent of `src`.
103 ///
104 /// Fourth, `dst`'s validity is satisfied. It is a given of this proof that the
105 /// referent is `DV`-valid for `Dst`. It is guaranteed to remain so, as either
106 /// of the following hold:
107 /// - So long as `dst` is active, no mutation of the referent is allowed except
108 ///   via `dst` itself.
109 /// - The set of `DV`-valid referents of `dst` is a superset of the set of
110 ///   `SV`-valid referents of `src`. Thus, any value written via `src` is
111 ///   guaranteed to be a `DV`-valid referent of `dst`.
112 pub unsafe trait TryTransmuteFromPtr<
113     Src: ?Sized,
114     A: Aliasing,
115     SV: Validity,
116     DV: Validity,
117     C: CastExact<Src, Self>,
118     R,
119 >
120 {
121 }
122 
123 #[allow(missing_copy_implementations, missing_debug_implementations)]
124 pub enum BecauseMutationCompatible {}
125 
126 // SAFETY:
127 // - Forwards transmutation: By `Dst: MutationCompatible<Src, A, SV, DV, _>`, we
128 //   know that at least one of the following holds:
129 //   - So long as `dst: Ptr<Dst>` is active, no mutation of its referent is
130 //     allowed except via `dst` itself if either of the following hold:
131 //     - Aliasing is `Exclusive`, in which case, so long as the `Dst` `Ptr`
132 //       exists, no mutation is permitted except via that `Ptr`
133 //     - Aliasing is `Shared`, `Src: Immutable`, and `Dst: Immutable`, in which
134 //       case no mutation is possible via either `Ptr`
135 //   - Since the underlying cast is size-preserving, `dst` addresses the same
136 //     referent as `src`. By `Dst: TransmuteFrom<Src, SV, DV>`, the set of
137 //     `DV`-valid referents of `dst` is a superset of the set of `SV`-valid
138 //     referents of `src`.
139 // - Reverse transmutation: Since the underlying cast is size-preserving, `dst`
140 //   addresses the same referent as `src`. By `Src: TransmuteFrom<Dst, DV, SV>`,
141 //   the set of `DV`-valid referents of `src` is a subset of the set of
142 //   `SV`-valid referents of `dst`.
143 // - No safe code, given access to `src` and `dst`, can cause undefined
144 //   behavior: By `Dst: MutationCompatible<Src, A, SV, DV, _>`, at least one of
145 //   the following holds:
146 //   - `A` is `Exclusive`
147 //   - `Src: Immutable` and `Dst: Immutable`
148 //   - `Dst: InvariantsEq<Src>`, which guarantees that `Src` and `Dst` have the
149 //     same invariants, and permit interior mutation on the same byte ranges
150 unsafe impl<Src, Dst, SV, DV, A, C, R>
151     TryTransmuteFromPtr<Src, A, SV, DV, C, (BecauseMutationCompatible, R)> for Dst
152 where
153     A: Aliasing,
154     SV: Validity,
155     DV: Validity,
156     Src: TransmuteFrom<Dst, DV, SV> + ?Sized,
157     Dst: MutationCompatible<Src, A, SV, DV, R> + ?Sized,
158     C: CastExact<Src, Dst>,
159 {
160 }
161 
162 // SAFETY:
163 // - Forwards transmutation: Since aliasing is `Shared` and `Src: Immutable`,
164 //   `src` does not permit mutation of its referent.
165 // - Reverse transmutation: Since aliasing is `Shared` and `Dst: Immutable`,
166 //   `dst` does not permit mutation of its referent.
167 // - No safe code, given access to `src` and `dst`, can cause undefined
168 //   behavior: `Src: Immutable` and `Dst: Immutable`
169 unsafe impl<Src, Dst, SV, DV, C> TryTransmuteFromPtr<Src, Shared, SV, DV, C, BecauseImmutable>
170     for Dst
171 where
172     SV: Validity,
173     DV: Validity,
174     Src: Immutable + ?Sized,
175     Dst: Immutable + ?Sized,
176     C: CastExact<Src, Dst>,
177 {
178 }
179 
180 /// Denotes that `src: Ptr<Src, (A, _, SV)>` and `dst: Ptr<Self, (A, _, DV)>`,
181 /// referencing the same referent at the same time, cannot be used by safe code
182 /// to break library safety invariants of `Src` or `Self`.
183 ///
184 /// # Safety
185 ///
186 /// At least one of the following must hold:
187 /// - `Src: Read<A, _>` and `Self: Read<A, _>`
188 /// - `Self: InvariantsEq<Src>`, and, for some `V`:
189 ///   - `Dst: TransmuteFrom<Src, V, V>`
190 ///   - `Src: TransmuteFrom<Dst, V, V>`
191 pub unsafe trait MutationCompatible<Src: ?Sized, A: Aliasing, SV, DV, R> {}
192 
193 #[allow(missing_copy_implementations, missing_debug_implementations)]
194 pub enum BecauseRead {}
195 
196 // SAFETY: `Src: Read<A, _>` and `Dst: Read<A, _>`.
197 unsafe impl<Src: ?Sized, Dst: ?Sized, A: Aliasing, SV: Validity, DV: Validity, R>
198     MutationCompatible<Src, A, SV, DV, (BecauseRead, R)> for Dst
199 where
200     Src: Read<A, R>,
201     Dst: Read<A, R>,
202 {
203 }
204 
205 /// Denotes that two types have the same invariants.
206 ///
207 /// # Safety
208 ///
209 /// It is sound for safe code to operate on a `&T` and a `&Self` pointing to the
210 /// same referent at the same time - no such safe code can cause undefined
211 /// behavior.
212 pub unsafe trait InvariantsEq<T: ?Sized> {}
213 
214 // SAFETY: Trivially sound to have multiple `&T` pointing to the same referent.
215 unsafe impl<T: ?Sized> InvariantsEq<T> for T {}
216 
217 // SAFETY: `Dst: InvariantsEq<Src> + TransmuteFrom<Src, SV, DV>`, and `Src:
218 // TransmuteFrom<Dst, DV, SV>`.
219 unsafe impl<Src: ?Sized, Dst: ?Sized, A: Aliasing, SV: Validity, DV: Validity>
220     MutationCompatible<Src, A, SV, DV, BecauseInvariantsEq> for Dst
221 where
222     Src: TransmuteFrom<Dst, DV, SV>,
223     Dst: TransmuteFrom<Src, SV, DV> + InvariantsEq<Src>,
224 {
225 }
226 
227 #[allow(missing_debug_implementations, missing_copy_implementations)]
228 pub enum BecauseInvariantsEq {}
229 
230 macro_rules! unsafe_impl_invariants_eq {
231     ($tyvar:ident => $t:ty, $u:ty) => {{
232         crate::util::macros::__unsafe();
233         // SAFETY: The caller promises that this is sound.
234         unsafe impl<$tyvar> InvariantsEq<$t> for $u {}
235         // SAFETY: The caller promises that this is sound.
236         unsafe impl<$tyvar> InvariantsEq<$u> for $t {}
237     }};
238 }
239 
240 impl_transitive_transmute_from!(T => MaybeUninit<T> => T => Wrapping<T>);
241 impl_transitive_transmute_from!(T => Wrapping<T> => T => MaybeUninit<T>);
242 
243 // SAFETY: `ManuallyDrop<T>` has the same size and bit validity as `T` [1], and
244 // implements `Deref<Target = T>` [2]. Thus, it is already possible for safe
245 // code to obtain a `&T` and a `&ManuallyDrop<T>` to the same referent at the
246 // same time.
247 //
248 // [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
249 //
250 //   `ManuallyDrop<T>` is guaranteed to have the same layout and bit
251 //   validity as `T`
252 //
253 // [2] https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html#impl-Deref-for-ManuallyDrop%3CT%3E
254 unsafe impl<T: ?Sized> InvariantsEq<T> for ManuallyDrop<T> {}
255 // SAFETY: See previous safety comment.
256 unsafe impl<T: ?Sized> InvariantsEq<ManuallyDrop<T>> for T {}
257 
258 /// Transmutations which are always sound.
259 ///
260 /// `TransmuteFromPtr` is a shorthand for [`TryTransmuteFromPtr`] and
261 /// [`TransmuteFrom`].
262 ///
263 /// # Safety
264 ///
265 /// `Dst: TransmuteFromPtr<Src, A, SV, DV, _>` is equivalent to `Dst:
266 /// TryTransmuteFromPtr<Src, A, SV, DV, _> + TransmuteFrom<Src, SV, DV>`.
267 pub unsafe trait TransmuteFromPtr<
268     Src: ?Sized,
269     A: Aliasing,
270     SV: Validity,
271     DV: Validity,
272     C: CastExact<Src, Self>,
273     R,
274 >: TryTransmuteFromPtr<Src, A, SV, DV, C, R> + TransmuteFrom<Src, SV, DV>
275 {
276 }
277 
278 // SAFETY: The `where` bounds are equivalent to the safety invariant on
279 // `TransmuteFromPtr`.
280 unsafe impl<
281         Src: ?Sized,
282         Dst: ?Sized,
283         A: Aliasing,
284         SV: Validity,
285         DV: Validity,
286         C: CastExact<Src, Dst>,
287         R,
288     > TransmuteFromPtr<Src, A, SV, DV, C, R> for Dst
289 where
290     Dst: TransmuteFrom<Src, SV, DV> + TryTransmuteFromPtr<Src, A, SV, DV, C, R>,
291 {
292 }
293 
294 /// Denotes that any `SV`-valid `Src` may soundly be transmuted into a
295 /// `DV`-valid `Self`.
296 ///
297 /// # Safety
298 ///
299 /// Given `src: Ptr<Src, (_, _, SV)>` and `dst: Ptr<Dst, (_, _, DV)>`, if the
300 /// referents of `src` and `dst` are the same size, then the set of bit patterns
301 /// allowed to appear in `src`'s referent must be a subset of the set allowed to
302 /// appear in `dst`'s referent.
303 ///
304 /// If the referents are not the same size, then `Dst: TransmuteFrom<Src, SV,
305 /// DV>` conveys no safety guarantee.
306 pub unsafe trait TransmuteFrom<Src: ?Sized, SV, DV> {}
307 
308 /// Carries the ability to perform a size-preserving cast or conversion from a
309 /// raw pointer to `Src` to a raw pointer to `Self`.
310 ///
311 /// The cast/conversion is carried by the associated [`CastFrom`] type, and
312 /// may be a no-op cast (without updating pointer metadata) or a conversion
313 /// which updates pointer metadata.
314 ///
315 /// # Safety
316 ///
317 /// `SizeEq` on its own conveys no safety guarantee. Any safety guarantees come
318 /// from the safety invariants on the associated [`CastFrom`] type, specifically
319 /// the [`CastExact`] bound.
320 ///
321 /// [`CastFrom`]: SizeEq::CastFrom
322 /// [`CastExact`]: CastExact
323 pub trait SizeEq<Src: ?Sized> {
324     type CastFrom: CastExact<Src, Self>;
325 }
326 
327 impl<T: ?Sized> SizeEq<T> for T {
328     type CastFrom = cast::IdCast;
329 }
330 
331 // SAFETY: Since `Src: IntoBytes`, the set of valid `Src`'s is the set of
332 // initialized bit patterns, which is exactly the set allowed in the referent of
333 // any `Initialized` `Ptr`.
334 unsafe impl<Src, Dst> TransmuteFrom<Src, Valid, Initialized> for Dst
335 where
336     Src: IntoBytes + ?Sized,
337     Dst: ?Sized,
338 {
339 }
340 
341 // SAFETY: Since `Dst: FromBytes`, any initialized bit pattern may appear in the
342 // referent of a `Ptr<Dst, (_, _, Valid)>`. This is exactly equal to the set of
343 // bit patterns which may appear in the referent of any `Initialized` `Ptr`.
344 unsafe impl<Src, Dst> TransmuteFrom<Src, Initialized, Valid> for Dst
345 where
346     Src: ?Sized,
347     Dst: FromBytes + ?Sized,
348 {
349 }
350 
351 // FIXME(#2354): This seems like a smell - the soundness of this bound has
352 // nothing to do with `Src` or `Dst` - we're basically just saying `[u8; N]` is
353 // transmutable into `[u8; N]`.
354 
355 // SAFETY: The set of allowed bit patterns in the referent of any `Initialized`
356 // `Ptr` is the same regardless of referent type.
357 unsafe impl<Src, Dst> TransmuteFrom<Src, Initialized, Initialized> for Dst
358 where
359     Src: ?Sized,
360     Dst: ?Sized,
361 {
362 }
363 
364 // FIXME(#2354): This seems like a smell - the soundness of this bound has
365 // nothing to do with `Dst` - we're basically just saying that any type is
366 // transmutable into `MaybeUninit<[u8; N]>`.
367 
368 // SAFETY: A `Dst` with validity `Uninit` permits any byte sequence, and
369 // therefore can be transmuted from any value.
370 unsafe impl<Src, Dst, V> TransmuteFrom<Src, V, Uninit> for Dst
371 where
372     Src: ?Sized,
373     Dst: ?Sized,
374     V: Validity,
375 {
376 }
377 
378 // SAFETY:
379 // - `ManuallyDrop<T>` has the same size as `T` [1]
380 // - `ManuallyDrop<T>` has the same validity as `T` [1]
381 //
382 // [1] Per https://doc.rust-lang.org/1.81.0/std/mem/struct.ManuallyDrop.html:
383 //
384 //   `ManuallyDrop<T>` is guaranteed to have the same layout and bit validity as
385 //   `T`
386 #[allow(clippy::multiple_unsafe_ops_per_block)]
387 const _: () = unsafe { unsafe_impl_for_transparent_wrapper!(pub T: ?Sized => ManuallyDrop<T>) };
388 
389 // SAFETY:
390 // - `Unalign<T>` promises to have the same size as `T`.
391 // - `Unalign<T>` promises to have the same validity as `T`.
392 #[allow(clippy::multiple_unsafe_ops_per_block)]
393 const _: () = unsafe { unsafe_impl_for_transparent_wrapper!(pub T => Unalign<T>) };
394 // SAFETY: `Unalign<T>` promises to have the same size and validity as `T`.
395 // Given `u: &Unalign<T>`, it is already possible to obtain `let t =
396 // u.try_deref().unwrap()`. Because `Unalign<T>` has the same size as `T`, the
397 // returned `&T` must point to the same referent as `u`, and thus it must be
398 // sound for these two references to exist at the same time since it's already
399 // possible for safe code to get into this state.
400 #[allow(clippy::multiple_unsafe_ops_per_block)]
401 const _: () = unsafe { unsafe_impl_invariants_eq!(T => T, Unalign<T>) };
402 
403 // SAFETY:
404 // - `Wrapping<T>` has the same size as `T` [1].
405 // - `Wrapping<T>` has only one field, which is `pub` [2]. We are also
406 //   guaranteed per that `Wrapping<T>` has the same layout as `T` [1]. The only
407 //   way for both of these to be true simultaneously is for `Wrapping<T>` to
408 //   have the same bit validity as `T`. In particular, in order to change the
409 //   bit validity, one of the following would need to happen:
410 //   - `Wrapping` could change its `repr`, but this would violate the layout
411 //     guarantee.
412 //   - `Wrapping` could add or change its fields, but this would be a
413 //     stability-breaking change.
414 //
415 // [1] Per https://doc.rust-lang.org/1.85.0/core/num/struct.Wrapping.html#layout-1:
416 //
417 //   `Wrapping<T>` is guaranteed to have the same layout and ABI as `T`.
418 //
419 // [2] Definition from https://doc.rust-lang.org/1.85.0/core/num/struct.Wrapping.html:
420 //
421 //   ```
422 //   #[repr(transparent)]
423 //   pub struct Wrapping<T>(pub T);
424 //   ```
425 #[allow(clippy::multiple_unsafe_ops_per_block)]
426 const _: () = unsafe { unsafe_impl_for_transparent_wrapper!(pub T => Wrapping<T>) };
427 
428 // SAFETY: By the preceding safety proof, `Wrapping<T>` and `T` have the same
429 // layout and bit validity. Since a `Wrapping<T>`'s `T` field is `pub`, given
430 // `w: &Wrapping<T>`, it's possible to do `let t = &w.t`, which means that it's
431 // already possible for safe code to obtain a `&Wrapping<T>` and a `&T` pointing
432 // to the same referent at the same time. Thus, this must be sound.
433 #[allow(clippy::multiple_unsafe_ops_per_block)]
434 const _: () = unsafe { unsafe_impl_invariants_eq!(T => T, Wrapping<T>) };
435 
436 // SAFETY:
437 // - `UnsafeCell<T>` has the same size as `T` [1].
438 // - Per [1], `UnsafeCell<T>` has the same bit validity as `T`. Technically the
439 //   term "representation" doesn't guarantee this, but the subsequent sentence
440 //   in the documentation makes it clear that this is the intention.
441 //
442 // [1] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
443 //
444 //   `UnsafeCell<T>` has the same in-memory representation as its inner type
445 //   `T`. A consequence of this guarantee is that it is possible to convert
446 //   between `T` and `UnsafeCell<T>`.
447 #[allow(clippy::multiple_unsafe_ops_per_block)]
448 const _: () = unsafe { unsafe_impl_for_transparent_wrapper!(pub T: ?Sized => UnsafeCell<T>) };
449 
450 // SAFETY:
451 // - `Cell<T>` has the same size as `T` [1].
452 // - Per [1], `Cell<T>` has the same bit validity as `T`. Technically the term
453 //   "representation" doesn't guarantee this, but it does promise to have the
454 //   "same memory layout and caveats as `UnsafeCell<T>`." The `UnsafeCell` docs
455 //   [2] make it clear that bit validity is the intention even if that phrase
456 //   isn't used.
457 //
458 // [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.Cell.html#memory-layout:
459 //
460 //   `Cell<T>` has the same memory layout and caveats as `UnsafeCell<T>`. In
461 //   particular, this means that `Cell<T>` has the same in-memory representation
462 //   as its inner type `T`.
463 //
464 // [2] Per https://doc.rust-lang.org/1.81.0/core/cell/struct.UnsafeCell.html#memory-layout:
465 //
466 //   `UnsafeCell<T>` has the same in-memory representation as its inner type
467 //   `T`. A consequence of this guarantee is that it is possible to convert
468 //   between `T` and `UnsafeCell<T>`.
469 #[allow(clippy::multiple_unsafe_ops_per_block)]
470 const _: () = unsafe { unsafe_impl_for_transparent_wrapper!(pub T: ?Sized => Cell<T>) };
471 
472 impl_transitive_transmute_from!(T: ?Sized => Cell<T> => T => UnsafeCell<T>);
473 impl_transitive_transmute_from!(T: ?Sized => UnsafeCell<T> => T => Cell<T>);
474 
475 // SAFETY: `MaybeUninit<T>` has no validity requirements. Currently this is not
476 // explicitly guaranteed, but it's obvious from `MaybeUninit`'s documentation
477 // that this is the intention:
478 // https://doc.rust-lang.org/1.85.0/core/mem/union.MaybeUninit.html
479 unsafe impl<T> TransmuteFrom<T, Uninit, Valid> for MaybeUninit<T> {}
480 
481 impl<T> SizeEq<T> for MaybeUninit<T> {
482     type CastFrom = CastSizedExact;
483 }
484 
485 impl<T> SizeEq<MaybeUninit<T>> for T {
486     type CastFrom = CastSizedExact;
487 }
488 
489 #[cfg(test)]
490 mod tests {
491     use super::*;
492     use crate::pointer::cast::Project as _;
493 
494     fn test_size_eq<Src, Dst: SizeEq<Src>>(mut src: Src) {
495         let _: *mut Dst =
496             <Dst as SizeEq<Src>>::CastFrom::project(crate::pointer::PtrInner::from_mut(&mut src));
497     }
498 
499     #[test]
500     fn test_transmute_coverage() {
501         // SizeEq<T> for MaybeUninit<T>
502         test_size_eq::<u8, MaybeUninit<u8>>(0u8);
503 
504         // SizeEq<MaybeUninit<T>> for T
505         test_size_eq::<MaybeUninit<u8>, u8>(MaybeUninit::<u8>::new(0));
506 
507         // Transitive: MaybeUninit<T> -> Wrapping<T>
508         // T => MaybeUninit<T> => T => Wrapping<T>
509         test_size_eq::<u8, Wrapping<u8>>(0u8);
510 
511         // T => Wrapping<T> => T => MaybeUninit<T>
512         test_size_eq::<Wrapping<u8>, MaybeUninit<u8>>(Wrapping(0u8));
513 
514         // T: ?Sized => Cell<T> => T => UnsafeCell<T>
515         test_size_eq::<Cell<u8>, UnsafeCell<u8>>(Cell::new(0u8));
516 
517         // T: ?Sized => UnsafeCell<T> => T => Cell<T>
518         test_size_eq::<UnsafeCell<u8>, Cell<u8>>(UnsafeCell::new(0u8));
519     }
520 }
521