From f6bedf50017b9a837b3600a115f2eca9cdb3ca9d Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 15 Sep 2021 13:41:13 -0700 Subject: [PATCH 1/2] core::num::NonZero type alias --- library/core/src/num/mod.rs | 3 ++ library/core/src/num/nonzero.rs | 54 +++++++++++++++++++++++++++++++++ library/std/src/lib.rs | 1 + library/std/src/num.rs | 2 ++ 4 files changed, 60 insertions(+) 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")] From 585acd8ef43948d1ca374668c7f109f9bde752e5 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Wed, 15 Sep 2021 13:49:27 -0700 Subject: [PATCH 2/2] Delete NonZero_c_abominations --- library/std/src/os/raw/mod.rs | 56 ++++++------------- .../std/src/sys/unix/process/process_unix.rs | 7 +-- .../sys/unix/process/process_unsupported.rs | 5 +- .../src/sys/unix/process/process_vxworks.rs | 7 +-- library/std/src/sys/windows/c.rs | 4 +- 5 files changed, 27 insertions(+), 52 deletions(-) diff --git a/library/std/src/os/raw/mod.rs b/library/std/src/os/raw/mod.rs index 1e220ea30ab95..d9495d88a4022 100644 --- a/library/std/src/os/raw/mod.rs +++ b/library/std/src/os/raw/mod.rs @@ -11,9 +11,7 @@ #[cfg(test)] mod tests; -use core::num::*; - -macro_rules! type_alias_no_nz { +macro_rules! type_alias { { $Docfile:tt, $Alias:ident = $Real:ty; $( $Cfg:tt )* @@ -25,27 +23,7 @@ macro_rules! type_alias_no_nz { } } -// To verify that the NonZero types in this file's macro invocations correspond -// -// perl -n < library/std/src/os/raw/mod.rs -e 'next unless m/type_alias\!/; die "$_ ?" unless m/, (c_\w+) = (\w+), NonZero_(\w+) = NonZero(\w+)/; die "$_ ?" unless $3 eq $1 and $4 eq ucfirst $2' -// -// NB this does not check that the main c_* types are right. - -macro_rules! type_alias { - { - $Docfile:tt, $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty; - $( $Cfg:tt )* - } => { - type_alias_no_nz! { $Docfile, $Alias = $Real; $( $Cfg )* } - - #[doc = concat!("Type alias for `NonZero` version of [`", stringify!($Alias), "`]")] - #[unstable(feature = "raw_os_nonzero", issue = "82363")] - $( $Cfg )* - pub type $NZAlias = $NZReal; - } -} - -type_alias! { "char.md", c_char = u8, NonZero_c_char = NonZeroU8; +type_alias! { "char.md", c_char = u8; #[cfg(any( all( target_os = "linux", @@ -87,7 +65,7 @@ type_alias! { "char.md", c_char = u8, NonZero_c_char = NonZeroU8; ), all(target_os = "fuchsia", target_arch = "aarch64") ))]} -type_alias! { "char.md", c_char = i8, NonZero_c_char = NonZeroI8; +type_alias! { "char.md", c_char = i8; #[cfg(not(any( all( target_os = "linux", @@ -129,24 +107,24 @@ type_alias! { "char.md", c_char = i8, NonZero_c_char = NonZeroI8; ), all(target_os = "fuchsia", target_arch = "aarch64") )))]} -type_alias! { "schar.md", c_schar = i8, NonZero_c_schar = NonZeroI8; } -type_alias! { "uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; } -type_alias! { "short.md", c_short = i16, NonZero_c_short = NonZeroI16; } -type_alias! { "ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; } -type_alias! { "int.md", c_int = i32, NonZero_c_int = NonZeroI32; } -type_alias! { "uint.md", c_uint = u32, NonZero_c_uint = NonZeroU32; } -type_alias! { "long.md", c_long = i32, NonZero_c_long = NonZeroI32; +type_alias! { "schar.md", c_schar = i8; } +type_alias! { "uchar.md", c_uchar = u8; } +type_alias! { "short.md", c_short = i16; } +type_alias! { "ushort.md", c_ushort = u16; } +type_alias! { "int.md", c_int = i32; } +type_alias! { "uint.md", c_uint = u32; } +type_alias! { "long.md", c_long = i32; #[cfg(any(target_pointer_width = "32", windows))] } -type_alias! { "ulong.md", c_ulong = u32, NonZero_c_ulong = NonZeroU32; +type_alias! { "ulong.md", c_ulong = u32; #[cfg(any(target_pointer_width = "32", windows))] } -type_alias! { "long.md", c_long = i64, NonZero_c_long = NonZeroI64; +type_alias! { "long.md", c_long = i64; #[cfg(all(target_pointer_width = "64", not(windows)))] } -type_alias! { "ulong.md", c_ulong = u64, NonZero_c_ulong = NonZeroU64; +type_alias! { "ulong.md", c_ulong = u64; #[cfg(all(target_pointer_width = "64", not(windows)))] } -type_alias! { "longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; } -type_alias! { "ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; } -type_alias_no_nz! { "float.md", c_float = f32; } -type_alias_no_nz! { "double.md", c_double = f64; } +type_alias! { "longlong.md", c_longlong = i64; } +type_alias! { "ulonglong.md", c_ulonglong = u64; } +type_alias! { "float.md", c_float = f32; } +type_alias! { "double.md", c_double = f64; } #[stable(feature = "raw_os", since = "1.1.0")] #[doc(no_inline)] diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 12edf04a4e2e9..81ebfd50497c8 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -2,8 +2,7 @@ use crate::convert::{TryFrom, TryInto}; use crate::fmt; use crate::io::{self, Error, ErrorKind}; use crate::mem; -use crate::num::NonZeroI32; -use crate::os::raw::NonZero_c_int; +use crate::num::{NonZero, NonZeroI32}; use crate::ptr; use crate::sys; use crate::sys::cvt; @@ -625,7 +624,7 @@ impl ExitStatus { // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html . If it is not // true for a platform pretending to be Unix, the tests (our doctests, and also // procsss_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. - match NonZero_c_int::try_from(self.0) { + match NonZero::::try_from(self.0) { /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)), /* was zero, couldn't convert */ Err(_) => Ok(()), } @@ -684,7 +683,7 @@ impl fmt::Display for ExitStatus { } #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatusError(NonZero_c_int); +pub struct ExitStatusError(NonZero); impl Into for ExitStatusError { fn into(self) -> ExitStatus { diff --git a/library/std/src/sys/unix/process/process_unsupported.rs b/library/std/src/sys/unix/process/process_unsupported.rs index 7d549d060fd88..95b1cbe13fa14 100644 --- a/library/std/src/sys/unix/process/process_unsupported.rs +++ b/library/std/src/sys/unix/process/process_unsupported.rs @@ -2,8 +2,7 @@ use crate::convert::{TryFrom, TryInto}; use crate::fmt; use crate::io; use crate::io::ErrorKind; -use crate::num::NonZeroI32; -use crate::os::raw::NonZero_c_int; +use crate::num::{NonZero, NonZeroI32}; use crate::sys; use crate::sys::cvt; use crate::sys::pipe::AnonPipe; @@ -107,7 +106,7 @@ impl fmt::Display for ExitStatus { } #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatusError(NonZero_c_int); +pub struct ExitStatusError(NonZero); impl Into for ExitStatusError { fn into(self) -> ExitStatus { diff --git a/library/std/src/sys/unix/process/process_vxworks.rs b/library/std/src/sys/unix/process/process_vxworks.rs index c17822f512532..245154026e7ad 100644 --- a/library/std/src/sys/unix/process/process_vxworks.rs +++ b/library/std/src/sys/unix/process/process_vxworks.rs @@ -1,8 +1,7 @@ use crate::convert::{TryFrom, TryInto}; use crate::fmt; use crate::io::{self, Error, ErrorKind}; -use crate::num::NonZeroI32; -use crate::os::raw::NonZero_c_int; +use crate::num::{NonZero, NonZeroI32}; use crate::sys; use crate::sys::cvt; use crate::sys::process::process_common::*; @@ -196,7 +195,7 @@ impl ExitStatus { // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html . If it is not // true for a platform pretending to be Unix, the tests (our doctests, and also // procsss_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. - match NonZero_c_int::try_from(self.0) { + match NonZero::::try_from(self.0) { Ok(failure) => Err(ExitStatusError(failure)), Err(_) => Ok(()), } @@ -248,7 +247,7 @@ impl fmt::Display for ExitStatus { } #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatusError(NonZero_c_int); +pub struct ExitStatusError(NonZero); impl Into for ExitStatusError { fn into(self) -> ExitStatus { diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 6fb850d182889..a172b1efda7ac 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -4,7 +4,7 @@ #![cfg_attr(test, allow(dead_code))] #![unstable(issue = "none", feature = "windows_c")] -use crate::os::raw::NonZero_c_ulong; +use crate::num::NonZero; use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort}; use crate::ptr; @@ -19,7 +19,7 @@ pub use self::FILE_INFO_BY_HANDLE_CLASS::*; pub type DWORD_PTR = ULONG_PTR; pub type DWORD = c_ulong; -pub type NonZeroDWORD = NonZero_c_ulong; +pub type NonZeroDWORD = NonZero; pub type HANDLE = LPVOID; pub type HINSTANCE = HANDLE; pub type HMODULE = HINSTANCE;