@@ -20,7 +20,15 @@ use super::{IntErrorKind, ParseIntError};
2020///
2121/// # Safety
2222///
23- /// Types implementing this trait must be primitves that are valid when zeroed.
23+ /// Types implementing this trait must be primitives that are valid when zeroed.
24+ ///
25+ /// The associated `Self::NonZeroInner` type must have the same size+align as `Self`,
26+ /// but with a niche and bit validity making it so the following `transmutes` are sound:
27+ ///
28+ /// - `Self::NonZeroInner` to `Option<Self::NonZeroInner>`
29+ /// - `Option<Self::NonZeroInner>` to `Self`
30+ ///
31+ /// (And, consequently, `Self::NonZeroInner` to `Self`.)
2432#[ unstable(
2533 feature = "nonzero_internals" ,
2634 reason = "implementation detail which may disappear or be replaced at any time" ,
@@ -434,17 +442,11 @@ where
434442 // of some not-inlined function, LLVM don't have range metadata
435443 // to understand that the value cannot be zero.
436444 //
437- // SAFETY: `Self` is guaranteed to have the same layout as `Option<Self>`.
438- match unsafe { intrinsics:: transmute_unchecked ( self ) } {
439- None => {
440- // SAFETY: `NonZero` is guaranteed to only contain non-zero values, so this is unreachable.
441- unsafe { intrinsics:: unreachable ( ) }
442- }
443- Some ( Self ( inner) ) => {
444- // SAFETY: `T::NonZeroInner` is guaranteed to have the same layout as `T`.
445- unsafe { intrinsics:: transmute_unchecked ( inner) }
446- }
447- }
445+ // For now, using the transmute `assume`s the range at runtime.
446+ //
447+ // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity
448+ // of `.0` is such that this transmute is sound.
449+ unsafe { intrinsics:: transmute_unchecked ( self ) }
448450 }
449451}
450452
0 commit comments