Skip to content

Commit

Permalink
core::num::NonZero<N> type alias
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Sep 15, 2021
1 parent 2c7bc5e commit f6bedf5
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 0 deletions.
3 changes: 3 additions & 0 deletions library/core/src/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
54 changes: 54 additions & 0 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u16>` 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<N>`
/// 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<c_char>,
/// }
///
/// impl Separator {
/// pub fn new(ch: c_char) -> Option<Self> {
/// NonZero::<c_char>::new(ch).map(|ch| Separator { ch })
/// }
/// }
/// ```
#[unstable(feature = "nonzero_generic_type_alias", issue = "82363")]
pub type NonZero<N> = <N as IntegerPrimitive>::NonZero;

// Not exposed at any publicly accessible path, only via NonZero<N>.
#[unstable(feature = "nonzero_implementation_detail", issue = "none")]
pub trait IntegerPrimitive {
type NonZero;
}

macro_rules! impl_nonzero_fmt {
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
$(
Expand Down Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/num.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down

0 comments on commit f6bedf5

Please sign in to comment.