From 39260d9016db6925414541ad2dce6502dded3a64 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Wed, 21 Aug 2019 14:10:40 +0200 Subject: [PATCH 1/2] make abs, wrapping_abs, and overflowing_abs const functions --- src/libcore/num/mod.rs | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index b46e06f8d8ada..df1c00ccd184f 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1401,12 +1401,8 @@ $EndFeature, " ```"), #[stable(feature = "no_panic_abs", since = "1.13.0")] #[inline] - pub fn wrapping_abs(self) -> Self { - if self.is_negative() { - self.wrapping_neg() - } else { - self - } + pub const fn wrapping_abs(self) -> Self { + (self ^ (self >> ($BITS - 1))).wrapping_sub(self >> ($BITS - 1)) } } @@ -1764,12 +1760,8 @@ $EndFeature, " ```"), #[stable(feature = "no_panic_abs", since = "1.13.0")] #[inline] - pub fn overflowing_abs(self) -> (Self, bool) { - if self.is_negative() { - self.overflowing_neg() - } else { - (self, false) - } + pub const fn overflowing_abs(self) -> (Self, bool) { + (self ^ (self >> ($BITS - 1))).overflowing_sub(self >> ($BITS - 1)) } } @@ -1973,15 +1965,11 @@ $EndFeature, " #[stable(feature = "rust1", since = "1.0.0")] #[inline] #[rustc_inherit_overflow_checks] - pub fn abs(self) -> Self { - if self.is_negative() { - // Note that the #[inline] above means that the overflow - // semantics of this negation depend on the crate we're being - // inlined into. - -self - } else { - self - } + pub const fn abs(self) -> Self { + // Note that the #[inline] above means that the overflow + // semantics of the subtraction depend on the crate we're being + // inlined into. + (self ^ (self >> ($BITS - 1))) - (self >> ($BITS - 1)) } } From adee559659774054497fc36afea0076c334c0bb2 Mon Sep 17 00:00:00 2001 From: Trevor Spiteri Date: Wed, 21 Aug 2019 15:40:12 +0200 Subject: [PATCH 2/2] test const abs, wrapping_abs, and overflowing_abs --- src/test/ui/consts/const-int-overflowing-rpass.rs | 8 ++++++++ src/test/ui/consts/const-int-sign-rpass.rs | 6 ++++++ src/test/ui/consts/const-int-wrapping-rpass.rs | 8 ++++++++ 3 files changed, 22 insertions(+) diff --git a/src/test/ui/consts/const-int-overflowing-rpass.rs b/src/test/ui/consts/const-int-overflowing-rpass.rs index b619c7908aa22..9be87a6447cda 100644 --- a/src/test/ui/consts/const-int-overflowing-rpass.rs +++ b/src/test/ui/consts/const-int-overflowing-rpass.rs @@ -18,6 +18,10 @@ const SHR_B: (u32, bool) = 0x10u32.overflowing_shr(132); const NEG_A: (u32, bool) = 0u32.overflowing_neg(); const NEG_B: (u32, bool) = core::u32::MAX.overflowing_neg(); +const ABS_POS: (i32, bool) = 10i32.overflowing_abs(); +const ABS_NEG: (i32, bool) = (-10i32).overflowing_abs(); +const ABS_MIN: (i32, bool) = i32::min_value().overflowing_abs(); + fn main() { assert_eq!(ADD_A, (7, false)); assert_eq!(ADD_B, (0, true)); @@ -36,4 +40,8 @@ fn main() { assert_eq!(NEG_A, (0, false)); assert_eq!(NEG_B, (1, true)); + + assert_eq!(ABS_POS, (10, false)); + assert_eq!(ABS_NEG, (10, false)); + assert_eq!(ABS_MIN, (i32::min_value(), true)); } diff --git a/src/test/ui/consts/const-int-sign-rpass.rs b/src/test/ui/consts/const-int-sign-rpass.rs index 05726cb228647..dc46fce39a93c 100644 --- a/src/test/ui/consts/const-int-sign-rpass.rs +++ b/src/test/ui/consts/const-int-sign-rpass.rs @@ -11,6 +11,9 @@ const SIGNUM_POS: i32 = 10i32.signum(); const SIGNUM_NIL: i32 = 0i32.signum(); const SIGNUM_NEG: i32 = (-42i32).signum(); +const ABS_A: i32 = 10i32.abs(); +const ABS_B: i32 = (-10i32).abs(); + fn main() { assert!(NEGATIVE_A); assert!(!NEGATIVE_B); @@ -20,4 +23,7 @@ fn main() { assert_eq!(SIGNUM_POS, 1); assert_eq!(SIGNUM_NIL, 0); assert_eq!(SIGNUM_NEG, -1); + + assert_eq!(ABS_A, 10); + assert_eq!(ABS_B, 10); } diff --git a/src/test/ui/consts/const-int-wrapping-rpass.rs b/src/test/ui/consts/const-int-wrapping-rpass.rs index 73147d7912d19..2bbad99a52a90 100644 --- a/src/test/ui/consts/const-int-wrapping-rpass.rs +++ b/src/test/ui/consts/const-int-wrapping-rpass.rs @@ -18,6 +18,10 @@ const SHR_B: u32 = 128u32.wrapping_shr(128); const NEG_A: u32 = 5u32.wrapping_neg(); const NEG_B: u32 = 1234567890u32.wrapping_neg(); +const ABS_POS: i32 = 10i32.wrapping_abs(); +const ABS_NEG: i32 = (-10i32).wrapping_abs(); +const ABS_MIN: i32 = i32::min_value().wrapping_abs(); + fn main() { assert_eq!(ADD_A, 255); assert_eq!(ADD_B, 199); @@ -36,4 +40,8 @@ fn main() { assert_eq!(NEG_A, 4294967291); assert_eq!(NEG_B, 3060399406); + + assert_eq!(ABS_POS, 10); + assert_eq!(ABS_NEG, 10); + assert_eq!(ABS_MIN, i32::min_value()); }