diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 59b68cbe9c0ce..550b2889f3522 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -59,6 +59,9 @@ pub use dec2flt::ParseFloatError; #[stable(feature = "rust1", since = "1.0.0")] pub use error::ParseIntError; +#[unstable(feature = "nonzero_generic_type_alias", issue = "82363")] +pub use nonzero::NonZero; + #[stable(feature = "nonzero", since = "1.28.0")] pub use nonzero::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize}; diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index dd9b9330aee2b..fb7c7a72b3aaa 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -8,6 +8,55 @@ use super::from_str_radix; use super::{IntErrorKind, ParseIntError}; use crate::intrinsics; +/// Generic type alias for the non-zero type that corresponds to each integer +/// primitive. +/// +/// This type alias simply provides an alternative spelling of the various +/// `NonZero` structs found in [`core::num`]. For example `NonZero` refers +/// to the struct [`core::num::NonZeroU16`]. +/// +/// **Note:** this is *not* intended for writing code that is generic over +/// multiple types of non-zero integers. The relevant trait bound you would need +/// for that is not exposed. The only thing this is, is an alternative spelling. +/// +/// # Example +/// +/// Where this comes in handy is if the primitive types themselves are being +/// used via a type alias, such as [`std::os::raw::c_char`][c_char]. The +/// `c_char` type refers to either `i8` or `u8` depending on whether the +/// platform's C character type is signed or unsigned, and without `NonZero` +/// there is not a straightforward way to name either `NonZeroI8` or `NonZeroU8` +/// depending on which one a non-zero `c_char` corresponds to. +/// +/// [c_char]: ../../std/os/raw/type.c_char.html +/// +/// ``` +/// #![feature(nonzero_generic_type_alias)] +/// +/// use std::num::NonZero; +/// use std::os::raw::c_char; +/// +/// // A separator that we're planning to use with nul-terminated C strings, +/// // where \0 would be nonsensical. +/// pub struct Separator { +/// ch: NonZero, +/// } +/// +/// impl Separator { +/// pub fn new(ch: c_char) -> Option { +/// NonZero::::new(ch).map(|ch| Separator { ch }) +/// } +/// } +/// ``` +#[unstable(feature = "nonzero_generic_type_alias", issue = "82363")] +pub type NonZero = ::NonZero; + +// Not exposed at any publicly accessible path, only via NonZero. +#[unstable(feature = "nonzero_implementation_detail", issue = "none")] +pub trait IntegerPrimitive { + type NonZero; +} + macro_rules! impl_nonzero_fmt { ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { $( @@ -41,6 +90,11 @@ macro_rules! nonzero_integers { #[rustc_nonnull_optimization_guaranteed] pub struct $Ty($Int); + #[unstable(feature = "nonzero_implementation_detail", issue = "none")] + impl IntegerPrimitive for $Int { + type NonZero = $Ty; + } + impl $Ty { /// Creates a non-zero without checking whether the value is non-zero. /// This results in undefined behaviour if the value is zero. diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 83c6ba0e6ea45..f0392131b9ad6 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -301,6 +301,7 @@ #![feature(new_uninit)] #![feature(nll)] #![feature(nonnull_slice_from_raw_parts)] +#![feature(nonzero_generic_type_alias)] #![feature(once_cell)] #![feature(panic_info_message)] #![feature(panic_internals)] diff --git a/library/std/src/num.rs b/library/std/src/num.rs index 46064bd283770..37081f515967e 100644 --- a/library/std/src/num.rs +++ b/library/std/src/num.rs @@ -19,6 +19,8 @@ pub use core::num::Wrapping; #[stable(feature = "rust1", since = "1.0.0")] pub use core::num::{FpCategory, ParseFloatError, ParseIntError, TryFromIntError}; +#[unstable(feature = "nonzero_generic_type_alias", issue = "82363")] +pub use core::num::NonZero; #[stable(feature = "signed_nonzero", since = "1.34.0")] pub use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize}; #[stable(feature = "nonzero", since = "1.28.0")]