From 80b6ba7b36f8fa5fc543e9dd505e109c21899eae Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 9 Apr 2024 15:52:44 +0200 Subject: [PATCH] Implement add for Uint* more consistently --- CHANGELOG.md | 4 +++ packages/std/src/math/uint128.rs | 44 +++++++++++++++++----------- packages/std/src/math/uint256.rs | 37 +++++++++++++++--------- packages/std/src/math/uint512.rs | 49 +++++++++++++++++++------------- packages/std/src/math/uint64.rs | 42 ++++++++++++++++++--------- 5 files changed, 114 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab17265f9b..e61db91aed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,12 +18,16 @@ and this project adheres to ([#2070]) - cosmwasm-std: The decimal types now implement `TryFrom` for their respective integer representations ([#2075]) +- cosmwasm-std: Implement `&T + T` and `&T op &T` for `Uint64`, `Uint128`, + `Uint256` and `Uint512`; improve panic message for `Uint64::add` and + `Uint512::add` ([#2092]) [#1983]: https://github.com/CosmWasm/cosmwasm/pull/1983 [#2057]: https://github.com/CosmWasm/cosmwasm/pull/2057 [#2058]: https://github.com/CosmWasm/cosmwasm/pull/2058 [#2068]: https://github.com/CosmWasm/cosmwasm/pull/2068 [#2075]: https://github.com/CosmWasm/cosmwasm/pull/2075 +[#2092]: https://github.com/CosmWasm/cosmwasm/pull/2092 ### Changed diff --git a/packages/std/src/math/uint128.rs b/packages/std/src/math/uint128.rs index 70005efbfe..9ee5c9841c 100644 --- a/packages/std/src/math/uint128.rs +++ b/packages/std/src/math/uint128.rs @@ -372,21 +372,14 @@ impl Add for Uint128 { type Output = Self; fn add(self, rhs: Self) -> Self { - Uint128( + Self( self.u128() .checked_add(rhs.u128()) .expect("attempt to add with overflow"), ) } } - -impl<'a> Add<&'a Uint128> for Uint128 { - type Output = Self; - - fn add(self, rhs: &'a Uint128) -> Self { - self + *rhs - } -} +forward_ref_binop!(impl Add, add for Uint128, Uint128); impl Sub for Uint128 { type Output = Self; @@ -811,10 +804,6 @@ mod tests { let a = Uint128(12345); let b = Uint128(23456); - // test + with owned and reference right hand side - assert_eq!(a + b, Uint128(35801)); - assert_eq!(a + &b, Uint128(35801)); - // test - with owned and reference right hand side assert_eq!(b - a, Uint128(11111)); assert_eq!(b - &a, Uint128(11111)); @@ -842,11 +831,32 @@ mod tests { } #[test] - #[should_panic] + #[allow(clippy::op_ref)] + fn uint128_add_works() { + assert_eq!( + Uint128::from(2u32) + Uint128::from(1u32), + Uint128::from(3u32) + ); + assert_eq!( + Uint128::from(2u32) + Uint128::from(0u32), + Uint128::from(2u32) + ); + + // works for refs + let a = Uint128::from(10u32); + let b = Uint128::from(3u32); + let expected = Uint128::from(13u32); + assert_eq!(a + b, expected); + assert_eq!(a + &b, expected); + assert_eq!(&a + b, expected); + assert_eq!(&a + &b, expected); + } + + #[test] + #[should_panic(expected = "attempt to add with overflow")] fn uint128_add_overflow_panics() { - // almost_max is 2^128 - 10 - let almost_max = Uint128(340282366920938463463374607431768211446); - let _ = almost_max + Uint128(12); + let max = Uint128::MAX; + let _ = max + Uint128(12); } #[test] diff --git a/packages/std/src/math/uint256.rs b/packages/std/src/math/uint256.rs index 06dbcb9331..6b4814feea 100644 --- a/packages/std/src/math/uint256.rs +++ b/packages/std/src/math/uint256.rs @@ -447,14 +447,7 @@ impl Add for Uint256 { ) } } - -impl<'a> Add<&'a Uint256> for Uint256 { - type Output = Self; - - fn add(self, rhs: &'a Uint256) -> Self { - self + *rhs - } -} +forward_ref_binop!(impl Add, add for Uint256, Uint256); impl Sub for Uint256 { type Output = Self; @@ -1324,10 +1317,6 @@ mod tests { let a = Uint256::from(12345u32); let b = Uint256::from(23456u32); - // test + with owned and reference right hand side - assert_eq!(a + b, Uint256::from(35801u32)); - assert_eq!(a + &b, Uint256::from(35801u32)); - // test - with owned and reference right hand side assert_eq!(b - a, Uint256::from(11111u32)); assert_eq!(b - &a, Uint256::from(11111u32)); @@ -1355,7 +1344,29 @@ mod tests { } #[test] - #[should_panic] + #[allow(clippy::op_ref)] + fn uint256_add_works() { + assert_eq!( + Uint256::from(2u32) + Uint256::from(1u32), + Uint256::from(3u32) + ); + assert_eq!( + Uint256::from(2u32) + Uint256::from(0u32), + Uint256::from(2u32) + ); + + // works for refs + let a = Uint256::from(10u32); + let b = Uint256::from(3u32); + let expected = Uint256::from(13u32); + assert_eq!(a + b, expected); + assert_eq!(a + &b, expected); + assert_eq!(&a + b, expected); + assert_eq!(&a + &b, expected); + } + + #[test] + #[should_panic(expected = "attempt to add with overflow")] fn uint256_add_overflow_panics() { let max = Uint256::new([255u8; 32]); let _ = max + Uint256::from(12u32); diff --git a/packages/std/src/math/uint512.rs b/packages/std/src/math/uint512.rs index 2d4d05217c..2842b726bd 100644 --- a/packages/std/src/math/uint512.rs +++ b/packages/std/src/math/uint512.rs @@ -421,17 +421,14 @@ impl Add for Uint512 { type Output = Self; fn add(self, rhs: Self) -> Self { - Uint512(self.0.checked_add(rhs.0).unwrap()) - } -} - -impl<'a> Add<&'a Uint512> for Uint512 { - type Output = Self; - - fn add(self, rhs: &'a Uint512) -> Self { - Uint512(self.0.checked_add(rhs.0).unwrap()) + Self( + self.0 + .checked_add(rhs.0) + .expect("attempt to add with overflow"), + ) } } +forward_ref_binop!(impl Add, add for Uint512, Uint512); impl Sub for Uint512 { type Output = Self; @@ -1027,14 +1024,6 @@ mod tests { let a = Uint512::from(12345u32); let b = Uint512::from(23456u32); - // test + with owned and reference right hand side - assert_eq!(a + b, Uint512::from(35801u32)); - assert_eq!(a + &b, Uint512::from(35801u32)); - - // test - with owned and reference right hand side - assert_eq!(b - a, Uint512::from(11111u32)); - assert_eq!(b - &a, Uint512::from(11111u32)); - // test += with owned and reference right hand side let mut c = Uint512::from(300000u32); c += b; @@ -1058,9 +1047,31 @@ mod tests { } #[test] - #[should_panic] + #[allow(clippy::op_ref)] + fn uint512_add_works() { + assert_eq!( + Uint512::from(2u32) + Uint512::from(1u32), + Uint512::from(3u32) + ); + assert_eq!( + Uint512::from(2u32) + Uint512::from(0u32), + Uint512::from(2u32) + ); + + // works for refs + let a = Uint512::from(10u32); + let b = Uint512::from(3u32); + let expected = Uint512::from(13u32); + assert_eq!(a + b, expected); + assert_eq!(a + &b, expected); + assert_eq!(&a + b, expected); + assert_eq!(&a + &b, expected); + } + + #[test] + #[should_panic(expected = "attempt to add with overflow")] fn uint512_add_overflow_panics() { - let max = Uint512::new([255u8; 64]); + let max = Uint512::MAX; let _ = max + Uint512::from(12u32); } diff --git a/packages/std/src/math/uint64.rs b/packages/std/src/math/uint64.rs index b663855d8e..188115b4ac 100644 --- a/packages/std/src/math/uint64.rs +++ b/packages/std/src/math/uint64.rs @@ -345,17 +345,14 @@ impl Add for Uint64 { type Output = Self; fn add(self, rhs: Self) -> Self { - Uint64(self.u64().checked_add(rhs.u64()).unwrap()) - } -} - -impl<'a> Add<&'a Uint64> for Uint64 { - type Output = Self; - - fn add(self, rhs: &'a Uint64) -> Self { - Uint64(self.u64().checked_add(rhs.u64()).unwrap()) + Self( + self.u64() + .checked_add(rhs.u64()) + .expect("attempt to add with overflow"), + ) } } +forward_ref_binop!(impl Add, add for Uint64, Uint64); impl Sub for Uint64 { type Output = Self; @@ -732,10 +729,6 @@ mod tests { let a = Uint64(12345); let b = Uint64(23456); - // test + with owned and reference right hand side - assert_eq!(a + b, Uint64(35801)); - assert_eq!(a + &b, Uint64(35801)); - // test - with owned and reference right hand side assert_eq!((b.checked_sub(a)).unwrap(), Uint64(11111)); @@ -753,6 +746,29 @@ mod tests { assert_eq!(operation, OverflowOperation::Sub); } + #[test] + #[allow(clippy::op_ref)] + fn uint64_add_works() { + assert_eq!(Uint64::from(2u32) + Uint64::from(1u32), Uint64::from(3u32)); + assert_eq!(Uint64::from(2u32) + Uint64::from(0u32), Uint64::from(2u32)); + + // works for refs + let a = Uint64::from(10u32); + let b = Uint64::from(3u32); + let expected = Uint64::from(13u32); + assert_eq!(a + b, expected); + assert_eq!(a + &b, expected); + assert_eq!(&a + b, expected); + assert_eq!(&a + &b, expected); + } + + #[test] + #[should_panic(expected = "attempt to add with overflow")] + fn uint64_add_overflow_panics() { + let max = Uint64::MAX; + let _ = max + Uint64(12); + } + #[test] #[allow(clippy::op_ref)] fn uint64_sub_works() {