Skip to content

Commit

Permalink
Add signed num::NonZeroI* types
Browse files Browse the repository at this point in the history
Multiple people have asked for them, in
rust-lang#49137.
Given that the unsigned ones already exist,
they are very easy to add and not an additional maintenance burden.
  • Loading branch information
SimonSapin authored and Vardhan Thigle committed Jan 31, 2019
1 parent 8371c7e commit bb1cd33
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 18 deletions.
36 changes: 21 additions & 15 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ use ops;
use str::FromStr;

macro_rules! impl_nonzero_fmt {
( ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
$(
#[stable(feature = "nonzero", since = "1.28.0")]
#[$stability]
impl fmt::$Trait for $Ty {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand All @@ -31,7 +31,7 @@ macro_rules! doc_comment {
}

macro_rules! nonzero_integers {
( $( $Ty: ident($Int: ty); )+ ) => {
( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
$(
doc_comment! {
concat!("An integer that is known not to equal zero.
Expand All @@ -41,10 +41,10 @@ For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!(
```rust
use std::mem::size_of;
assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
">());
```"),
#[stable(feature = "nonzero", since = "1.28.0")]
#[$stability]
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(1)]
Expand All @@ -57,14 +57,14 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st
/// # Safety
///
/// The value must not be zero.
#[stable(feature = "nonzero", since = "1.28.0")]
#[$stability]
#[inline]
pub const unsafe fn new_unchecked(n: $Int) -> Self {
$Ty(n)
}

/// Create a non-zero if the given value is not zero.
#[stable(feature = "nonzero", since = "1.28.0")]
#[$stability]
#[inline]
pub fn new(n: $Int) -> Option<Self> {
if n != 0 {
Expand All @@ -75,7 +75,7 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st
}

/// Returns the value as a primitive type.
#[stable(feature = "nonzero", since = "1.28.0")]
#[$stability]
#[inline]
pub const fn get(self) -> $Int {
self.0
Expand All @@ -91,19 +91,25 @@ assert_eq!(size_of::<Option<std::num::", stringify!($Ty), ">>(), size_of::<", st
}

impl_nonzero_fmt! {
(Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
#[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
}
)+
}
}

nonzero_integers! {
NonZeroU8(u8);
NonZeroU16(u16);
NonZeroU32(u32);
NonZeroU64(u64);
NonZeroU128(u128);
NonZeroUsize(usize);
#[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
#[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
#[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
#[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
#[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
#[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
#[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
#[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
#[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
#[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
#[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
#[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

/// Provides intentionally-wrapped arithmetic on `T`.
Expand Down
10 changes: 9 additions & 1 deletion src/libcore/tests/nonzero.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::num::NonZeroU32;
use core::num::{NonZeroU32, NonZeroI32};
use core::option::Option;
use core::option::Option::{Some, None};
use std::mem::size_of;
Expand All @@ -13,6 +13,7 @@ fn test_create_nonzero_instance() {
#[test]
fn test_size_nonzero_in_option() {
assert_eq!(size_of::<NonZeroU32>(), size_of::<Option<NonZeroU32>>());
assert_eq!(size_of::<NonZeroI32>(), size_of::<Option<NonZeroI32>>());
}

#[test]
Expand Down Expand Up @@ -118,3 +119,10 @@ fn test_from_nonzero() {
let num: u32 = nz.into();
assert_eq!(num, 1u32);
}

#[test]
fn test_from_signed_nonzero() {
let nz = NonZeroI32::new(1).unwrap();
let num: i32 = nz.into();
assert_eq!(num, 1i32);
}
4 changes: 2 additions & 2 deletions src/test/ui/try-block/try-block-bad-type.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ LL | Err("")?; //~ ERROR the trait bound `i32: std::convert::From<&str>`
| ^^^^^^^^ the trait `std::convert::From<&str>` is not implemented for `i32`
|
= help: the following implementations were found:
<i32 as std::convert::From<bool>>
<i32 as std::convert::From<core::num::NonZeroI32>>
<i32 as std::convert::From<i16>>
<i32 as std::convert::From<i8>>
<i32 as std::convert::From<u16>>
<i32 as std::convert::From<u8>>
and 2 others
= note: required by `std::convert::From::from`

error[E0271]: type mismatch resolving `<std::result::Result<i32, i32> as std::ops::Try>::Ok == &str`
Expand Down

0 comments on commit bb1cd33

Please sign in to comment.