From 77749ef26c1c7f7055d9833c5e593baae503c35a 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 (cherry picked from commit 80b6ba7b36f8fa5fc543e9dd505e109c21899eae) # Conflicts: # CHANGELOG.md --- CHANGELOG.md | 8 ++++++ 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, 118 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c558371de..6ab63036c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ and this project adheres to ## [Unreleased] +### Added + +- 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]) + +[#2092]: https://github.com/CosmWasm/cosmwasm/pull/2092 + ### Changed - cosmwasm-vm: Read `Region` from Wasm memory as bytes and convert to `Region` diff --git a/packages/std/src/math/uint128.rs b/packages/std/src/math/uint128.rs index 0aebf6b992..db59d469d3 100644 --- a/packages/std/src/math/uint128.rs +++ b/packages/std/src/math/uint128.rs @@ -363,21 +363,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; @@ -781,10 +774,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)); @@ -814,11 +803,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 6422dee764..3e1d55971e 100644 --- a/packages/std/src/math/uint256.rs +++ b/packages/std/src/math/uint256.rs @@ -435,14 +435,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; @@ -1289,10 +1282,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)); @@ -1322,7 +1311,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 c4dd9e3f52..a6de3592b8 100644 --- a/packages/std/src/math/uint512.rs +++ b/packages/std/src/math/uint512.rs @@ -415,17 +415,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; @@ -993,14 +990,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; @@ -1026,9 +1015,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 f405b23643..e71abd977a 100644 --- a/packages/std/src/math/uint64.rs +++ b/packages/std/src/math/uint64.rs @@ -326,17 +326,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; @@ -704,10 +701,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)); @@ -727,6 +720,29 @@ mod tests { assert_eq!((operand1, operand2), (a.to_string(), b.to_string())); } + #[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() {