diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 695e87aaabf8a..f5d765e690db4 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -59,6 +59,8 @@ pub use dec2flt::ParseFloatError; #[stable(feature = "rust1", since = "1.0.0")] pub use error::ParseIntError; +pub(crate) use nonzero::NonZero; + #[stable(feature = "nonzero", since = "1.28.0")] pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; @@ -482,7 +484,7 @@ impl u8 { Self = u8, ActualT = u8, SignedT = i8, - NonZeroT = NonZeroU8, + NonZeroT = NonZero, BITS = 8, MAX = 255, rot = 2, @@ -1097,7 +1099,7 @@ impl u16 { Self = u16, ActualT = u16, SignedT = i16, - NonZeroT = NonZeroU16, + NonZeroT = NonZero, BITS = 16, MAX = 65535, rot = 4, @@ -1146,7 +1148,7 @@ impl u32 { Self = u32, ActualT = u32, SignedT = i32, - NonZeroT = NonZeroU32, + NonZeroT = NonZero, BITS = 32, MAX = 4294967295, rot = 8, @@ -1170,7 +1172,7 @@ impl u64 { Self = u64, ActualT = u64, SignedT = i64, - NonZeroT = NonZeroU64, + NonZeroT = NonZero, BITS = 64, MAX = 18446744073709551615, rot = 12, @@ -1194,7 +1196,7 @@ impl u128 { Self = u128, ActualT = u128, SignedT = i128, - NonZeroT = NonZeroU128, + NonZeroT = NonZero, BITS = 128, MAX = 340282366920938463463374607431768211455, rot = 16, @@ -1220,7 +1222,7 @@ impl usize { Self = usize, ActualT = u16, SignedT = isize, - NonZeroT = NonZeroUsize, + NonZeroT = NonZero, BITS = 16, MAX = 65535, rot = 4, @@ -1245,7 +1247,7 @@ impl usize { Self = usize, ActualT = u32, SignedT = isize, - NonZeroT = NonZeroUsize, + NonZeroT = NonZero, BITS = 32, MAX = 4294967295, rot = 8, @@ -1270,7 +1272,7 @@ impl usize { Self = usize, ActualT = u64, SignedT = isize, - NonZeroT = NonZeroUsize, + NonZeroT = NonZero, BITS = 64, MAX = 18446744073709551615, rot = 12, diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 2df38ab5848af..715c3a0b8ac34 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -8,6 +8,69 @@ use super::from_str_radix; use super::{IntErrorKind, ParseIntError}; use crate::intrinsics; +mod private { + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + #[const_trait] + pub trait Sealed {} +} + +/// A marker trait for primitive types which can be zero. +/// +/// This is an implementation detail for [`NonZero`](NonZero) which may disappear or be replaced at any time. +#[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" +)] +#[const_trait] +pub trait ZeroablePrimitive: Sized + Copy + private::Sealed { + type NonZero; +} + +#[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" +)] +pub(crate) type NonZero = ::NonZero; + +macro_rules! impl_zeroable_primitive { + ($NonZero:ident ( $primitive:ty )) => { + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + impl const private::Sealed for $primitive {} + + #[unstable( + feature = "nonzero_internals", + reason = "implementation detail which may disappear or be replaced at any time", + issue = "none" + )] + impl const ZeroablePrimitive for $primitive { + type NonZero = $NonZero; + } + }; +} + +impl_zeroable_primitive!(NonZeroU8(u8)); +impl_zeroable_primitive!(NonZeroU16(u16)); +impl_zeroable_primitive!(NonZeroU32(u32)); +impl_zeroable_primitive!(NonZeroU64(u64)); +impl_zeroable_primitive!(NonZeroU128(u128)); +impl_zeroable_primitive!(NonZeroUsize(usize)); +impl_zeroable_primitive!(NonZeroI8(i8)); +impl_zeroable_primitive!(NonZeroI16(i16)); +impl_zeroable_primitive!(NonZeroI32(i32)); +impl_zeroable_primitive!(NonZeroI64(i64)); +impl_zeroable_primitive!(NonZeroI128(i128)); +impl_zeroable_primitive!(NonZeroIsize(isize)); + macro_rules! impl_nonzero_fmt { ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { $( diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index 11a53aaf122ec..bbbbd61c4b1c9 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -3,7 +3,7 @@ macro_rules! uint_impl { Self = $SelfT:ty, ActualT = $ActualT:ident, SignedT = $SignedT:ident, - NonZeroT = $NonZeroT:ident, + NonZeroT = $NonZeroT:ty, // There are all for use *only* in doc comments. // As such, they're all passed as literals -- passing them as a string @@ -842,6 +842,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn checked_ilog2(self) -> Option { + // FIXME: Simply use `NonZero::new` once it is actually generic. if let Some(x) = <$NonZeroT>::new(self) { Some(x.ilog2()) } else { @@ -864,6 +865,7 @@ macro_rules! uint_impl { without modifying the original"] #[inline] pub const fn checked_ilog10(self) -> Option { + // FIXME: Simply use `NonZero::new` once it is actually generic. if let Some(x) = <$NonZeroT>::new(self) { Some(x.ilog10()) } else { diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 3d58afd26eacc..4a64faf9b3f2a 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -12,7 +12,7 @@ use crate::iter::{ }; use crate::marker::PhantomData; use crate::mem::{self, SizedTypeProperties}; -use crate::num::NonZeroUsize; +use crate::num::{NonZero, NonZeroUsize}; use crate::ptr::{self, invalid, invalid_mut, NonNull}; use super::{from_raw_parts, from_raw_parts_mut}; @@ -1305,12 +1305,12 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] } #[must_use = "iterators are lazy and do nothing unless consumed"] pub struct Windows<'a, T: 'a> { v: &'a [T], - size: NonZeroUsize, + size: NonZero, } impl<'a, T: 'a> Windows<'a, T> { #[inline] - pub(super) fn new(slice: &'a [T], size: NonZeroUsize) -> Self { + pub(super) fn new(slice: &'a [T], size: NonZero) -> Self { Self { v: slice, size } } }