1
1
//! Definitions of integer that is known not to equal zero.
2
2
3
- use super :: { IntErrorKind , ParseIntError } ;
3
+ use super :: { IntErrorKind , ParseIntError , TryFromIntError } ;
4
4
use crate :: cmp:: Ordering ;
5
5
use crate :: hash:: { Hash , Hasher } ;
6
6
use crate :: marker:: { Freeze , StructuralPartialEq } ;
7
7
use crate :: ops:: { BitOr , BitOrAssign , Div , DivAssign , Neg , Rem , RemAssign } ;
8
8
use crate :: panic:: { RefUnwindSafe , UnwindSafe } ;
9
9
use crate :: str:: FromStr ;
10
- use crate :: { fmt, intrinsics, ptr, ub_checks} ;
10
+ use crate :: { fmt, hint , intrinsics, ptr, slice , ub_checks} ;
11
11
12
12
/// A marker trait for primitive types which can be zero.
13
13
///
@@ -273,6 +273,77 @@ where
273
273
}
274
274
}
275
275
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
+ }
276
347
#[ stable( feature = "nonzero_bitor" , since = "1.45.0" ) ]
277
348
impl < T > BitOr for NonZero < T >
278
349
where
@@ -421,6 +492,45 @@ where
421
492
}
422
493
}
423
494
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
+
424
534
/// Returns the contained value as a primitive type.
425
535
#[ stable( feature = "nonzero" , since = "1.28.0" ) ]
426
536
#[ rustc_const_stable( feature = "const_nonzero_get" , since = "1.34.0" ) ]
@@ -441,6 +551,31 @@ where
441
551
unsafe { intrinsics:: transmute_unchecked ( self ) }
442
552
}
443
553
}
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
+ }
444
579
445
580
macro_rules! nonzero_integer {
446
581
(
0 commit comments