@@ -20,7 +20,15 @@ use super::{IntErrorKind, ParseIntError};
20
20
///
21
21
/// # Safety
22
22
///
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`.)
24
32
#[ unstable(
25
33
feature = "nonzero_internals" ,
26
34
reason = "implementation detail which may disappear or be replaced at any time" ,
@@ -434,17 +442,11 @@ where
434
442
// of some not-inlined function, LLVM don't have range metadata
435
443
// to understand that the value cannot be zero.
436
444
//
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 ) }
448
450
}
449
451
}
450
452
0 commit comments