diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1ab7481b7baae..048f8f0223b65 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -422,3 +422,11 @@ pub mod simd { } include!("primitive_docs.rs"); + +mod sealed { + /// This trait being unreachable from outside the crate + /// prevents outside implementations of our extension traits. + /// This allows adding more trait methods in the future. + #[unstable(feature = "sealed", issue = "none")] + pub trait Sealed {} +} diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 5bdd78aa2dea4..533258ef00196 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -6,7 +6,33 @@ use crate::str::FromStr; use super::from_str_radix; use super::{IntErrorKind, ParseIntError}; -use crate::intrinsics; +use crate::{intrinsics, sealed::Sealed}; + +/// A number that is known not to equal zero. +/// +/// # Safety +/// +/// Implementors of this trait must not have a memory representation for zero. +#[unstable(feature = "nonzero_trait", issue = "95157")] +pub unsafe trait NonZero: Sealed { + /// The primitive scalar type. + /// + /// # Examples + /// + /// ## Type Aliases + /// + /// When referring to an integer type through an alias, this can be used to + /// state its primitive type. + /// + /// ``` + /// use std::num::{NonZero, NonZeroU32}; + /// + /// type NonZeroInt = NonZeroU32; + /// + /// let n: ::Scalar = 1; + /// ``` + type Scalar; +} macro_rules! impl_nonzero_fmt { ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => { @@ -41,6 +67,14 @@ macro_rules! nonzero_integers { #[rustc_nonnull_optimization_guaranteed] pub struct $Ty($Int); + #[unstable(feature = "sealed", issue = "none")] + impl Sealed for $Ty {} + + #[unstable(feature = "nonzero_trait", issue = "95157")] + unsafe impl NonZero for $Ty { + type Scalar = $Int; + } + impl $Ty { /// Creates a non-zero without checking whether the value is non-zero. /// This results in undefined behaviour if the value is zero.