diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index f80f839282781..2fbc5f7aa76cc 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1175,7 +1175,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 } } @@ -1529,12 +1529,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()) } } @@ -3017,7 +3013,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 } @@ -3322,7 +3318,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 289b1236cf1e2..82057868b73bb 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 5ab712015dfc3..140fd57ecb802 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)); }