Skip to content

Commit 56edb12

Browse files
Use newly added panicking_add/panicking_sub for Timestamp math (backport #2098) (#2103)
* Add panicking_sub to Uint64/Uint128/Uint256/Uint512 (cherry picked from commit 547efed) # Conflicts: # CHANGELOG.md * Improve docs of Timestamp::minus_* and use panicking_sub (cherry picked from commit 242cc1f) # Conflicts: # CHANGELOG.md * Add Uint{64,128,256,512}::panicking_add (cherry picked from commit a74aba0) # Conflicts: # CHANGELOG.md * Add #[inline] annotations to plus_seconds/minus_seconds (cherry picked from commit bbb788d) * Make overflow behaviour explicit for Timestamp (cherry picked from commit b265b33) # Conflicts: # CHANGELOG.md * Add PR link to new CHANGELOG entries (cherry picked from commit 198001e) # Conflicts: # CHANGELOG.md * Fix CHANGELOG --------- Co-authored-by: Simon Warta <[email protected]>
1 parent 5b5a32d commit 56edb12

File tree

6 files changed

+214
-39
lines changed

6 files changed

+214
-39
lines changed

CHANGELOG.md

+5
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@ and this project adheres to
1111
- cosmwasm-std: Implement `&T + T` and `&T op &T` for `Uint64`, `Uint128`,
1212
`Uint256` and `Uint512`; improve panic message for `Uint64::add` and
1313
`Uint512::add` ([#2092])
14+
- cosmwasm-std: Add `Uint{64,128,256,512}::panicking_add` and `::panicking_sub`
15+
which are like the `Add`/`Sub` implementations but `const`. ([#2098])
16+
- cosmwasm-std: Let `Timestamp::plus_nanos`/`::minus_nanos` use
17+
`Uint64::panicking_add`/`::panicking_sub` and document overflows. ([#2098])
1418

1519
[#2092]: https://github.com/CosmWasm/cosmwasm/pull/2092
20+
[#2098]: https://github.com/CosmWasm/cosmwasm/pull/2098
1621

1722
## [2.0.1] - 2024-04-03
1823

packages/std/src/math/uint128.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,28 @@ impl Uint128 {
263263
Self(self.0.saturating_pow(exp))
264264
}
265265

266+
/// This is the same as [`Uint128::add`] but const.
267+
///
268+
/// Panics on overflow.
269+
#[must_use = "this returns the result of the operation, without modifying the original"]
270+
pub const fn panicking_add(self, other: Self) -> Self {
271+
match self.0.checked_add(other.u128()) {
272+
None => panic!("attempt to add with overflow"),
273+
Some(sum) => Self(sum),
274+
}
275+
}
276+
277+
/// This is the same as [`Uint128::sub`] but const.
278+
///
279+
/// Panics on overflow.
280+
#[must_use = "this returns the result of the operation, without modifying the original"]
281+
pub const fn panicking_sub(self, other: Self) -> Self {
282+
match self.0.checked_sub(other.u128()) {
283+
None => panic!("attempt to subtract with overflow"),
284+
Some(diff) => Self(diff),
285+
}
286+
}
287+
266288
#[must_use = "this returns the result of the operation, without modifying the original"]
267289
pub const fn abs_diff(self, other: Self) -> Self {
268290
Self(if self.0 < other.0 {
@@ -372,11 +394,7 @@ impl Add<Uint128> for Uint128 {
372394
type Output = Self;
373395

374396
fn add(self, rhs: Self) -> Self {
375-
Self(
376-
self.u128()
377-
.checked_add(rhs.u128())
378-
.expect("attempt to add with overflow"),
379-
)
397+
self.panicking_add(rhs)
380398
}
381399
}
382400
forward_ref_binop!(impl Add, add for Uint128, Uint128);
@@ -385,11 +403,7 @@ impl Sub<Uint128> for Uint128 {
385403
type Output = Self;
386404

387405
fn sub(self, rhs: Self) -> Self {
388-
Uint128(
389-
self.u128()
390-
.checked_sub(rhs.u128())
391-
.expect("attempt to subtract with overflow"),
392-
)
406+
self.panicking_sub(rhs)
393407
}
394408
}
395409
forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
@@ -1176,6 +1190,21 @@ mod tests {
11761190
assert_eq!(a, Uint128::from(1u32));
11771191
}
11781192

1193+
#[test]
1194+
fn uint128_panicking_sub_works() {
1195+
let a = Uint128::new(5);
1196+
let b = Uint128::new(3);
1197+
assert_eq!(a.panicking_sub(b), Uint128::new(2));
1198+
}
1199+
1200+
#[test]
1201+
#[should_panic(expected = "attempt to subtract with overflow")]
1202+
fn uint128_panicking_sub_panics_on_overflow() {
1203+
let a = Uint128::ZERO;
1204+
let b = Uint128::ONE;
1205+
let _diff = a.panicking_sub(b);
1206+
}
1207+
11791208
#[test]
11801209
fn uint128_abs_diff_works() {
11811210
let a = Uint128::from(42u32);

packages/std/src/math/uint256.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,28 @@ impl Uint256 {
335335
Self(self.0.saturating_pow(exp))
336336
}
337337

338+
/// This is the same as [`Uint256::add`] but const.
339+
///
340+
/// Panics on overflow.
341+
#[must_use = "this returns the result of the operation, without modifying the original"]
342+
pub const fn panicking_add(self, other: Self) -> Self {
343+
match self.0.checked_add(other.0) {
344+
None => panic!("attempt to add with overflow"),
345+
Some(sum) => Self(sum),
346+
}
347+
}
348+
349+
/// This is the same as [`Uint256::sub`] but const.
350+
///
351+
/// Panics on overflow.
352+
#[must_use = "this returns the result of the operation, without modifying the original"]
353+
pub const fn panicking_sub(self, other: Self) -> Self {
354+
match self.0.checked_sub(other.0) {
355+
None => panic!("attempt to subtract with overflow"),
356+
Some(diff) => Self(diff),
357+
}
358+
}
359+
338360
#[must_use = "this returns the result of the operation, without modifying the original"]
339361
pub const fn abs_diff(self, other: Self) -> Self {
340362
Self(self.0.abs_diff(other.0))
@@ -440,11 +462,7 @@ impl Add<Uint256> for Uint256 {
440462
type Output = Self;
441463

442464
fn add(self, rhs: Self) -> Self {
443-
Self(
444-
self.0
445-
.checked_add(rhs.0)
446-
.expect("attempt to add with overflow"),
447-
)
465+
self.panicking_add(rhs)
448466
}
449467
}
450468
forward_ref_binop!(impl Add, add for Uint256, Uint256);
@@ -453,11 +471,7 @@ impl Sub<Uint256> for Uint256 {
453471
type Output = Self;
454472

455473
fn sub(self, rhs: Self) -> Self {
456-
Self(
457-
self.0
458-
.checked_sub(rhs.0)
459-
.expect("attempt to subtract with overflow"),
460-
)
474+
self.panicking_sub(rhs)
461475
}
462476
}
463477
forward_ref_binop!(impl Sub, sub for Uint256, Uint256);
@@ -1723,6 +1737,21 @@ mod tests {
17231737
assert_eq!(a, Uint256::from(1u32));
17241738
}
17251739

1740+
#[test]
1741+
fn uint256_panicking_sub_works() {
1742+
let a = Uint256::from(5u32);
1743+
let b = Uint256::from(3u32);
1744+
assert_eq!(a.panicking_sub(b), Uint256::from(2u32));
1745+
}
1746+
1747+
#[test]
1748+
#[should_panic(expected = "attempt to subtract with overflow")]
1749+
fn uint256_panicking_sub_panics_on_overflow() {
1750+
let a = Uint256::ZERO;
1751+
let b = Uint256::ONE;
1752+
let _diff = a.panicking_sub(b);
1753+
}
1754+
17261755
#[test]
17271756
fn uint256_abs_diff_works() {
17281757
let a = Uint256::from(42u32);

packages/std/src/math/uint512.rs

+39-6
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,28 @@ impl Uint512 {
298298
Self(self.0.saturating_pow(exp))
299299
}
300300

301+
/// This is the same as [`Uint512::add`] but const.
302+
///
303+
/// Panics on overflow.
304+
#[must_use = "this returns the result of the operation, without modifying the original"]
305+
pub const fn panicking_add(self, other: Self) -> Self {
306+
match self.0.checked_add(other.0) {
307+
None => panic!("attempt to add with overflow"),
308+
Some(sum) => Self(sum),
309+
}
310+
}
311+
312+
/// This is the same as [`Uint512::sub`] but const.
313+
///
314+
/// Panics on overflow.
315+
#[must_use = "this returns the result of the operation, without modifying the original"]
316+
pub const fn panicking_sub(self, other: Self) -> Self {
317+
match self.0.checked_sub(other.0) {
318+
None => panic!("attempt to subtract with overflow"),
319+
Some(diff) => Self(diff),
320+
}
321+
}
322+
301323
#[must_use = "this returns the result of the operation, without modifying the original"]
302324
pub const fn abs_diff(self, other: Self) -> Self {
303325
Self(self.0.abs_diff(other.0))
@@ -421,11 +443,7 @@ impl Add<Uint512> for Uint512 {
421443
type Output = Self;
422444

423445
fn add(self, rhs: Self) -> Self {
424-
Self(
425-
self.0
426-
.checked_add(rhs.0)
427-
.expect("attempt to add with overflow"),
428-
)
446+
self.panicking_add(rhs)
429447
}
430448
}
431449
forward_ref_binop!(impl Add, add for Uint512, Uint512);
@@ -434,7 +452,7 @@ impl Sub<Uint512> for Uint512 {
434452
type Output = Self;
435453

436454
fn sub(self, rhs: Self) -> Self {
437-
Uint512(self.0.checked_sub(rhs.0).unwrap())
455+
self.panicking_sub(rhs)
438456
}
439457
}
440458
forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
@@ -1370,6 +1388,21 @@ mod tests {
13701388
assert_eq!(a, Uint512::from(1u32));
13711389
}
13721390

1391+
#[test]
1392+
fn uint512_panicking_sub_works() {
1393+
let a = Uint512::from(5u32);
1394+
let b = Uint512::from(3u32);
1395+
assert_eq!(a.panicking_sub(b), Uint512::from(2u32));
1396+
}
1397+
1398+
#[test]
1399+
#[should_panic(expected = "attempt to subtract with overflow")]
1400+
fn uint512_panicking_sub_panics_on_overflow() {
1401+
let a = Uint512::ZERO;
1402+
let b = Uint512::ONE;
1403+
let _diff = a.panicking_sub(b);
1404+
}
1405+
13731406
#[test]
13741407
fn uint512_abs_diff_works() {
13751408
let a = Uint512::from(42u32);

packages/std/src/math/uint64.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,28 @@ impl Uint64 {
257257
Self(self.0.saturating_pow(exp))
258258
}
259259

260+
/// This is the same as [`Uint64::add`] but const.
261+
///
262+
/// Panics on overflow.
263+
#[must_use = "this returns the result of the operation, without modifying the original"]
264+
pub const fn panicking_add(self, other: Self) -> Self {
265+
match self.0.checked_add(other.u64()) {
266+
None => panic!("attempt to add with overflow"),
267+
Some(sum) => Self(sum),
268+
}
269+
}
270+
271+
/// This is the same as [`Uint64::sub`] but const.
272+
///
273+
/// Panics on overflow.
274+
#[must_use = "this returns the result of the operation, without modifying the original"]
275+
pub const fn panicking_sub(self, other: Self) -> Self {
276+
match self.0.checked_sub(other.u64()) {
277+
None => panic!("attempt to subtract with overflow"),
278+
Some(diff) => Self(diff),
279+
}
280+
}
281+
260282
#[must_use = "this returns the result of the operation, without modifying the original"]
261283
pub const fn abs_diff(self, other: Self) -> Self {
262284
Self(if self.0 < other.0 {
@@ -345,11 +367,7 @@ impl Add<Uint64> for Uint64 {
345367
type Output = Self;
346368

347369
fn add(self, rhs: Self) -> Self {
348-
Self(
349-
self.u64()
350-
.checked_add(rhs.u64())
351-
.expect("attempt to add with overflow"),
352-
)
370+
self.panicking_add(rhs)
353371
}
354372
}
355373
forward_ref_binop!(impl Add, add for Uint64, Uint64);
@@ -358,11 +376,7 @@ impl Sub<Uint64> for Uint64 {
358376
type Output = Self;
359377

360378
fn sub(self, rhs: Self) -> Self {
361-
Uint64(
362-
self.u64()
363-
.checked_sub(rhs.u64())
364-
.expect("attempt to subtract with overflow"),
365-
)
379+
self.panicking_sub(rhs)
366380
}
367381
}
368382
forward_ref_binop!(impl Sub, sub for Uint64, Uint64);
@@ -1088,6 +1102,21 @@ mod tests {
10881102
assert_eq!(a, Uint64::from(1u32));
10891103
}
10901104

1105+
#[test]
1106+
fn uint64_panicking_sub_works() {
1107+
let a = Uint64::new(5);
1108+
let b = Uint64::new(3);
1109+
assert_eq!(a.panicking_sub(b), Uint64::new(2));
1110+
}
1111+
1112+
#[test]
1113+
#[should_panic(expected = "attempt to subtract with overflow")]
1114+
fn uint64_panicking_sub_panics_on_overflow() {
1115+
let a = Uint64::ZERO;
1116+
let b = Uint64::ONE;
1117+
let _diff = a.panicking_sub(b);
1118+
}
1119+
10911120
#[test]
10921121
fn uint64_abs_diff_works() {
10931122
let a = Uint64::from(42u32);

0 commit comments

Comments
 (0)