From 3f671bc94450aff38d7fcd9243327a20cb553ee0 Mon Sep 17 00:00:00 2001 From: Ohad Ravid Date: Mon, 16 Nov 2020 15:38:22 +0200 Subject: [PATCH 1/3] Added `impl Div for u{0}` which cannot panic --- library/core/src/num/nonzero.rs | 30 +++++++++++++++++++++++++++++- library/core/tests/nonzero.rs | 8 ++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 716b4a90e5ec2..3355fb64ecfd1 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1,7 +1,7 @@ //! Definitions of integer that is known not to equal zero. use crate::fmt; -use crate::ops::{BitOr, BitOrAssign}; +use crate::ops::{BitOr, BitOrAssign, Div}; use crate::str::FromStr; use super::from_str_radix; @@ -263,3 +263,31 @@ nonzero_leading_trailing_zeros! { NonZeroI128(u128), -1i128; NonZeroIsize(usize), -1isize; } + +macro_rules! nonzero_integers_div { + ( $( $Ty: ident($Int: ty); )+ ) => { + $( + #[stable(feature = "nonzero_div", since = "1.50.0")] + impl Div<$Ty> for $Int { + type Output = $Int; + /// This operation rounds towards zero, + /// truncating any fractional part of the exact result, and cannot panic. + #[inline] + fn div(self, other: $Ty) -> $Int { + // SAFETY: div by zero is checked because `other` is a nonzero, + // and MIN/-1 is checked because `self` is an unsigned int. + unsafe { crate::intrinsics::unchecked_div(self, other.get()) } + } + } + )+ + } +} + +nonzero_integers_div! { + NonZeroU8(u8); + NonZeroU16(u16); + NonZeroU32(u32); + NonZeroU64(u64); + NonZeroU128(u128); + NonZeroUsize(usize); +} diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index b66c482c5e5e3..6ec3a04adc080 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -312,3 +312,11 @@ fn nonzero_trailing_zeros() { const TRAILING_ZEROS: u32 = NonZeroU16::new(1 << 2).unwrap().trailing_zeros(); assert_eq!(TRAILING_ZEROS, 2); } + +#[test] +fn test_nonzero_uint_div() { + let nz = NonZeroU32::new(1).unwrap(); + + let x: u32 = 42u32 / nz; + assert_eq!(x, 42u32); +} From 1e9e30dc404edaec5bf5ef9c1d88157a883da374 Mon Sep 17 00:00:00 2001 From: Ohad Ravid Date: Wed, 18 Nov 2020 07:48:03 +0200 Subject: [PATCH 2/3] Added `impl Rem for u{0}` which cannot panic --- library/core/src/num/nonzero.rs | 14 +++++++++++++- library/core/tests/nonzero.rs | 8 ++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 3355fb64ecfd1..e139facb6ea49 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -1,7 +1,7 @@ //! Definitions of integer that is known not to equal zero. use crate::fmt; -use crate::ops::{BitOr, BitOrAssign, Div}; +use crate::ops::{BitOr, BitOrAssign, Div, Rem}; use crate::str::FromStr; use super::from_str_radix; @@ -279,6 +279,18 @@ macro_rules! nonzero_integers_div { unsafe { crate::intrinsics::unchecked_div(self, other.get()) } } } + + #[stable(feature = "nonzero_div", since = "1.50.0")] + impl Rem<$Ty> for $Int { + type Output = $Int; + /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic. + #[inline] + fn rem(self, other: $Ty) -> $Int { + // SAFETY: rem by zero is checked because `other` is a nonzero, + // and MIN/-1 is checked because `self` is an unsigned int. + unsafe { crate::intrinsics::unchecked_rem(self, other.get()) } + } + } )+ } } diff --git a/library/core/tests/nonzero.rs b/library/core/tests/nonzero.rs index 6ec3a04adc080..c2c08522d0cae 100644 --- a/library/core/tests/nonzero.rs +++ b/library/core/tests/nonzero.rs @@ -320,3 +320,11 @@ fn test_nonzero_uint_div() { let x: u32 = 42u32 / nz; assert_eq!(x, 42u32); } + +#[test] +fn test_nonzero_uint_rem() { + let nz = NonZeroU32::new(10).unwrap(); + + let x: u32 = 42u32 % nz; + assert_eq!(x, 2u32); +} From 95866439125c1f81e9eb7a242d7e9f99e6d921b6 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 27 Dec 2020 03:17:30 -0800 Subject: [PATCH 3/3] Bump nonzero_div feature to Rust 1.51 --- 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 e139facb6ea49..5eb70026d7e77 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -267,7 +267,7 @@ nonzero_leading_trailing_zeros! { macro_rules! nonzero_integers_div { ( $( $Ty: ident($Int: ty); )+ ) => { $( - #[stable(feature = "nonzero_div", since = "1.50.0")] + #[stable(feature = "nonzero_div", since = "1.51.0")] impl Div<$Ty> for $Int { type Output = $Int; /// This operation rounds towards zero, @@ -280,7 +280,7 @@ macro_rules! nonzero_integers_div { } } - #[stable(feature = "nonzero_div", since = "1.50.0")] + #[stable(feature = "nonzero_div", since = "1.51.0")] impl Rem<$Ty> for $Int { type Output = $Int; /// This operation satisfies `n % d == n - (n / d) * d`, and cannot panic.