diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 6fb67ea9c9a..5b7d5f45d92 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1215,7 +1215,7 @@ $EndFeature, " ```"), #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline] - pub fn wrapping_neg(self) -> Self { + pub const fn wrapping_neg(self) -> Self { self.overflowing_neg().0 } } @@ -1569,12 +1569,8 @@ assert_eq!(", stringify!($SelfT), "::MIN.overflowing_neg(), (", stringify!($Self ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_neg(self) -> (Self, bool) { - if self == Self::min_value() { - (Self::min_value(), true) - } else { - (-self, false) - } + pub const fn overflowing_neg(self) -> (Self, bool) { + ((!self).wrapping_add(1), self == Self::min_value()) } } @@ -3092,7 +3088,7 @@ assert_eq!(100", stringify!($SelfT), ".wrapping_rem_euclid(10), 0); /// ``` #[stable(feature = "num_wrapping", since = "1.2.0")] #[inline] - pub fn wrapping_neg(self) -> Self { + pub const fn wrapping_neg(self) -> Self { self.overflowing_neg().0 } @@ -3397,7 +3393,7 @@ assert_eq!(2", stringify!($SelfT), ".overflowing_neg(), (-2i32 as ", stringify!( ```"), #[inline] #[stable(feature = "wrapping", since = "1.7.0")] - pub fn overflowing_neg(self) -> (Self, bool) { + pub const fn overflowing_neg(self) -> (Self, bool) { ((!self).wrapping_add(1), self != 0) } } diff --git a/src/test/run-pass/const-int-overflowing.rs b/src/test/run-pass/const-int-overflowing.rs index 289b1236cf1..82057868b73 100644 --- a/src/test/run-pass/const-int-overflowing.rs +++ b/src/test/run-pass/const-int-overflowing.rs @@ -13,6 +13,9 @@ const SHL_B: (u32, bool) = 0x1u32.overflowing_shl(132); const SHR_A: (u32, bool) = 0x10u32.overflowing_shr(4); 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(); + fn ident(ident: T) -> T { ident } @@ -32,4 +35,7 @@ fn main() { assert_eq!(SHR_A, ident((0x1, false))); assert_eq!(SHR_B, ident((0x1, true))); + + assert_eq!(NEG_A, ident((0, false))); + assert_eq!(NEG_B, ident((1, true))); } diff --git a/src/test/run-pass/const-int-wrapping.rs b/src/test/run-pass/const-int-wrapping.rs index 5ab712015df..140fd57ecb8 100644 --- a/src/test/run-pass/const-int-wrapping.rs +++ b/src/test/run-pass/const-int-wrapping.rs @@ -13,6 +13,9 @@ const SHL_B: u32 = 1u32.wrapping_shl(128); const SHR_A: u32 = 128u32.wrapping_shr(7); const SHR_B: u32 = 128u32.wrapping_shr(128); +const NEG_A: u32 = 5u32.wrapping_neg(); +const NEG_B: u32 = 1234567890u32.wrapping_neg(); + fn ident(ident: T) -> T { ident } @@ -32,4 +35,7 @@ fn main() { assert_eq!(SHR_A, ident(1)); assert_eq!(SHR_B, ident(128)); + + assert_eq!(NEG_A, ident(4294967291)); + assert_eq!(NEG_B, ident(3060399406)); }