11//! Definitions of integer that is known not to equal zero.
22
3- use super :: { IntErrorKind , ParseIntError } ;
3+ use super :: { IntErrorKind , ParseIntError , TryFromIntError } ;
44use crate :: cmp:: Ordering ;
55use crate :: hash:: { Hash , Hasher } ;
66use crate :: marker:: { Freeze , StructuralPartialEq } ;
77use crate :: ops:: { BitOr , BitOrAssign , Div , DivAssign , Neg , Rem , RemAssign } ;
88use crate :: panic:: { RefUnwindSafe , UnwindSafe } ;
99use crate :: str:: FromStr ;
10- use crate :: { fmt, hint, intrinsics, ptr, ub_checks} ;
10+ use crate :: { fmt, hint, intrinsics, ptr, slice , ub_checks} ;
1111
1212/// A marker trait for primitive types which can be zero.
1313///
@@ -273,6 +273,77 @@ where
273273 }
274274}
275275
276+ #[ stable( feature = "more_from_nonzero" , since = "CURRENT_RUSTC_VERSION" ) ]
277+ impl < ' a , T > From < & ' a NonZero < T > > for & ' a T
278+ where
279+ T : ZeroablePrimitive ,
280+ {
281+ #[ inline]
282+ fn from ( nonzero : & ' a NonZero < T > ) -> & ' a T {
283+ nonzero. as_ref ( )
284+ }
285+ }
286+
287+ #[ stable( feature = "more_from_nonzero" , since = "CURRENT_RUSTC_VERSION" ) ]
288+ impl < ' a , T > From < & ' a [ NonZero < T > ] > for & ' a [ T ]
289+ where
290+ T : ZeroablePrimitive ,
291+ {
292+ #[ inline]
293+ fn from ( nonzero : & ' a [ NonZero < T > ] ) -> & ' a [ T ] {
294+ nonzero. as_zeroable ( )
295+ }
296+ }
297+
298+ #[ stable( feature = "more_from_nonzero" , since = "CURRENT_RUSTC_VERSION" ) ]
299+ impl < T , const N : usize > From < [ NonZero < T > ; N ] > for [ T ; N ]
300+ where
301+ T : ZeroablePrimitive ,
302+ {
303+ #[ inline]
304+ fn from ( nonzero : [ NonZero < T > ; N ] ) -> [ T ; N ] {
305+ nonzero. into_zeroable ( )
306+ }
307+ }
308+
309+ #[ stable( feature = "more_from_nonzero" , since = "CURRENT_RUSTC_VERSION" ) ]
310+ impl < ' a , T > TryFrom < & ' a T > for & ' a NonZero < T >
311+ where
312+ T : ZeroablePrimitive ,
313+ {
314+ type Error = TryFromIntError ;
315+
316+ #[ inline]
317+ fn try_from ( zeroable : & ' a T ) -> Result < & ' a NonZero < T > , TryFromIntError > {
318+ NonZero :: from_ref ( zeroable) . ok_or ( TryFromIntError ( ( ) ) )
319+ }
320+ }
321+
322+ #[ stable( feature = "more_from_nonzero" , since = "CURRENT_RUSTC_VERSION" ) ]
323+ impl < ' a , T > TryFrom < & ' a [ T ] > for & ' a [ NonZero < T > ]
324+ where
325+ T : ZeroablePrimitive ,
326+ {
327+ type Error = TryFromIntError ;
328+
329+ #[ inline]
330+ fn try_from ( zeroable : & ' a [ T ] ) -> Result < & ' a [ NonZero < T > ] , TryFromIntError > {
331+ NonZero :: from_slice ( zeroable) . ok_or ( TryFromIntError ( ( ) ) )
332+ }
333+ }
334+
335+ #[ stable( feature = "more_from_nonzero" , since = "CURRENT_RUSTC_VERSION" ) ]
336+ impl < T , const N : usize > TryFrom < [ T ; N ] > for [ NonZero < T > ; N ]
337+ where
338+ T : ZeroablePrimitive ,
339+ {
340+ type Error = TryFromIntError ;
341+
342+ #[ inline]
343+ fn try_from ( zeroable : [ T ; N ] ) -> Result < [ NonZero < T > ; N ] , TryFromIntError > {
344+ NonZero :: from_array ( zeroable) . ok_or ( TryFromIntError ( ( ) ) )
345+ }
346+ }
276347#[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
277348impl < T > BitOr for NonZero < T >
278349where
@@ -421,6 +492,45 @@ where
421492 }
422493 }
423494
495+ /// Implementation of `From<&NonZero<T>> for &T`.
496+ #[ must_use]
497+ #[ inline]
498+ fn as_ref ( & self ) -> & T {
499+ // SAFETY: `repr(transparent)` ensures that `NonZero<T>` has same layout as `T`
500+ unsafe { & * ( ptr:: from_ref ( self ) . cast :: < T > ( ) ) }
501+ }
502+
503+ /// Implementation of `TryFrom<&T> for &NonZero<T>`.
504+ #[ must_use]
505+ #[ inline]
506+ fn from_ref ( n : & T ) -> Option < & Self > {
507+ // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
508+ // the same layout and size as `T`, with `0` representing `None`.
509+ let opt_n = unsafe { & * ( ptr:: from_ref ( n) . cast :: < Option < Self > > ( ) ) } ;
510+
511+ opt_n. as_ref ( )
512+ }
513+
514+ /// Implementation of `TryFrom<&[T]> for &[NonZero<T>]`.
515+ #[ must_use]
516+ #[ inline]
517+ fn from_slice ( n : & [ T ] ) -> Option < & [ Self ] > {
518+ if n. iter ( ) . all ( |x| NonZero :: new ( * x) . is_some ( ) ) {
519+ // SAFETY: We explicitly checked that all elements are nonzero, and because of `repr(transparent)`
520+ // the layout remains unchanged
521+ Some ( unsafe { & * ( slice:: from_raw_parts ( n. as_ptr ( ) . cast :: < NonZero < T > > ( ) , n. len ( ) ) ) } )
522+ } else {
523+ None
524+ }
525+ }
526+
527+ /// Implementation of `TryFrom<[T; N]> for [NonZero<T>; N]`.
528+ #[ must_use]
529+ #[ inline]
530+ fn from_array < const N : usize > ( n : [ T ; N ] ) -> Option < [ Self ; N ] > {
531+ n. try_map ( NonZero :: new)
532+ }
533+
424534 /// Returns the contained value as a primitive type.
425535 #[ stable( feature = "nonzero" , since = "1.28.0" ) ]
426536 #[ rustc_const_stable( feature = "const_nonzero_get" , since = "1.34.0" ) ]
@@ -441,6 +551,31 @@ where
441551 unsafe { intrinsics:: transmute_unchecked ( self ) }
442552 }
443553}
554+ impl < T > [ NonZero < T > ]
555+ where
556+ T : ZeroablePrimitive ,
557+ {
558+ /// Implementation of `From<&[NonZero<T>]> for &[T]`.
559+ #[ must_use]
560+ #[ inline]
561+ fn as_zeroable ( & self ) -> & [ T ] {
562+ // SAFETY: `repr(transparent)` ensures that `NonZero<T>` has same layout as `T`, and thus
563+ // `[NonZero<T>]` has same layout as `[T]`
564+ unsafe { & * ( slice:: from_raw_parts ( self . as_ptr ( ) . cast :: < T > ( ) , self . len ( ) ) ) }
565+ }
566+ }
567+
568+ impl < T , const N : usize > [ NonZero < T > ; N ]
569+ where
570+ T : ZeroablePrimitive ,
571+ {
572+ /// Implementation of `From<[NonZero<T>; N]> for [T; N]`.
573+ #[ must_use]
574+ #[ inline]
575+ fn into_zeroable ( self ) -> [ T ; N ] {
576+ self . map ( NonZero :: get)
577+ }
578+ }
444579
445580macro_rules! nonzero_integer {
446581 (
0 commit comments