From e34c698dbdc101f495b74f365124f0aea1c02e8c Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Sun, 20 Mar 2022 18:29:12 -0400 Subject: [PATCH 1/3] Create `NonZero` trait with primitive associated type This enables getting the primitive integer type for a nonzero type through a type alias. --- library/core/src/lib.rs | 8 ++++++++ library/core/src/num/nonzero.rs | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) 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..2a5083f86d097 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -6,7 +6,32 @@ 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. +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 +66,12 @@ macro_rules! nonzero_integers { #[rustc_nonnull_optimization_guaranteed] pub struct $Ty($Int); + impl Sealed for $Ty {} + + 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. From 545f836cbcf700d513c7ccdce2bcca63cb93e01b Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Sun, 20 Mar 2022 18:38:10 -0400 Subject: [PATCH 2/3] Add stability attributes --- library/core/src/num/nonzero.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 2a5083f86d097..a3ee74990a10c 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -13,6 +13,7 @@ use crate::{intrinsics, sealed::Sealed}; /// # Safety /// /// Implementors of this trait must not have a memory representation for zero. +#[unstable(feature = "nonzero_trait", issue = "none")] pub unsafe trait NonZero: Sealed { /// The primitive scalar type. /// @@ -66,8 +67,10 @@ 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 = "none")] unsafe impl NonZero for $Ty { type Scalar = $Int; } From f062242aca44b45aadc003b269d3d71d804739b9 Mon Sep 17 00:00:00 2001 From: Nikolai Vazquez Date: Sun, 20 Mar 2022 18:44:34 -0400 Subject: [PATCH 3/3] Add tracking issue --- library/core/src/num/nonzero.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index a3ee74990a10c..533258ef00196 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -13,7 +13,7 @@ use crate::{intrinsics, sealed::Sealed}; /// # Safety /// /// Implementors of this trait must not have a memory representation for zero. -#[unstable(feature = "nonzero_trait", issue = "none")] +#[unstable(feature = "nonzero_trait", issue = "95157")] pub unsafe trait NonZero: Sealed { /// The primitive scalar type. /// @@ -70,7 +70,7 @@ macro_rules! nonzero_integers { #[unstable(feature = "sealed", issue = "none")] impl Sealed for $Ty {} - #[unstable(feature = "nonzero_trait", issue = "none")] + #[unstable(feature = "nonzero_trait", issue = "95157")] unsafe impl NonZero for $Ty { type Scalar = $Int; }