Skip to content

Commit e29dbf7

Browse files
Use newly added panicking_add/panicking_sub for Timestamp math (backport #2098) (#2105)
* 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 * Use zero() and one() from functions in tests ZERO / ONE are not yet available in 1.4 --------- Co-authored-by: Simon Warta <[email protected]>
1 parent 1f8964f commit e29dbf7

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
### Changed
1823

packages/std/src/math/uint128.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,28 @@ impl Uint128 {
259259
Self(self.0.saturating_pow(exp))
260260
}
261261

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

365387
fn add(self, rhs: Self) -> Self {
366-
Self(
367-
self.u128()
368-
.checked_add(rhs.u128())
369-
.expect("attempt to add with overflow"),
370-
)
388+
self.panicking_add(rhs)
371389
}
372390
}
373391
forward_ref_binop!(impl Add, add for Uint128, Uint128);
@@ -376,11 +394,7 @@ impl Sub<Uint128> for Uint128 {
376394
type Output = Self;
377395

378396
fn sub(self, rhs: Self) -> Self {
379-
Uint128(
380-
self.u128()
381-
.checked_sub(rhs.u128())
382-
.expect("attempt to subtract with overflow"),
383-
)
397+
self.panicking_sub(rhs)
384398
}
385399
}
386400
forward_ref_binop!(impl Sub, sub for Uint128, Uint128);
@@ -1148,6 +1162,21 @@ mod tests {
11481162
assert_eq!(a, Uint128::from(1u32));
11491163
}
11501164

1165+
#[test]
1166+
fn uint128_panicking_sub_works() {
1167+
let a = Uint128::new(5);
1168+
let b = Uint128::new(3);
1169+
assert_eq!(a.panicking_sub(b), Uint128::new(2));
1170+
}
1171+
1172+
#[test]
1173+
#[should_panic(expected = "attempt to subtract with overflow")]
1174+
fn uint128_panicking_sub_panics_on_overflow() {
1175+
let a = Uint128::zero();
1176+
let b = Uint128::one();
1177+
let _diff = a.panicking_sub(b);
1178+
}
1179+
11511180
#[test]
11521181
fn uint128_abs_diff_works() {
11531182
let a = Uint128::from(42u32);

packages/std/src/math/uint256.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,28 @@ impl Uint256 {
329329
Self(self.0.saturating_pow(exp))
330330
}
331331

332+
/// This is the same as [`Uint256::add`] but const.
333+
///
334+
/// Panics on overflow.
335+
#[must_use = "this returns the result of the operation, without modifying the original"]
336+
pub const fn panicking_add(self, other: Self) -> Self {
337+
match self.0.checked_add(other.0) {
338+
None => panic!("attempt to add with overflow"),
339+
Some(sum) => Self(sum),
340+
}
341+
}
342+
343+
/// This is the same as [`Uint256::sub`] but const.
344+
///
345+
/// Panics on overflow.
346+
#[must_use = "this returns the result of the operation, without modifying the original"]
347+
pub const fn panicking_sub(self, other: Self) -> Self {
348+
match self.0.checked_sub(other.0) {
349+
None => panic!("attempt to subtract with overflow"),
350+
Some(diff) => Self(diff),
351+
}
352+
}
353+
332354
#[must_use = "this returns the result of the operation, without modifying the original"]
333355
pub const fn abs_diff(self, other: Self) -> Self {
334356
Self(self.0.abs_diff(other.0))
@@ -428,11 +450,7 @@ impl Add<Uint256> for Uint256 {
428450
type Output = Self;
429451

430452
fn add(self, rhs: Self) -> Self {
431-
Self(
432-
self.0
433-
.checked_add(rhs.0)
434-
.expect("attempt to add with overflow"),
435-
)
453+
self.panicking_add(rhs)
436454
}
437455
}
438456
forward_ref_binop!(impl Add, add for Uint256, Uint256);
@@ -441,11 +459,7 @@ impl Sub<Uint256> for Uint256 {
441459
type Output = Self;
442460

443461
fn sub(self, rhs: Self) -> Self {
444-
Self(
445-
self.0
446-
.checked_sub(rhs.0)
447-
.expect("attempt to subtract with overflow"),
448-
)
462+
self.panicking_sub(rhs)
449463
}
450464
}
451465
forward_ref_binop!(impl Sub, sub for Uint256, Uint256);
@@ -1690,6 +1704,21 @@ mod tests {
16901704
assert_eq!(a, Uint256::from(1u32));
16911705
}
16921706

1707+
#[test]
1708+
fn uint256_panicking_sub_works() {
1709+
let a = Uint256::from(5u32);
1710+
let b = Uint256::from(3u32);
1711+
assert_eq!(a.panicking_sub(b), Uint256::from(2u32));
1712+
}
1713+
1714+
#[test]
1715+
#[should_panic(expected = "attempt to subtract with overflow")]
1716+
fn uint256_panicking_sub_panics_on_overflow() {
1717+
let a = Uint256::zero();
1718+
let b = Uint256::one();
1719+
let _diff = a.panicking_sub(b);
1720+
}
1721+
16931722
#[test]
16941723
fn uint256_abs_diff_works() {
16951724
let a = Uint256::from(42u32);

packages/std/src/math/uint512.rs

+39-6
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,28 @@ impl Uint512 {
294294
Self(self.0.saturating_pow(exp))
295295
}
296296

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

417439
fn add(self, rhs: Self) -> Self {
418-
Self(
419-
self.0
420-
.checked_add(rhs.0)
421-
.expect("attempt to add with overflow"),
422-
)
440+
self.panicking_add(rhs)
423441
}
424442
}
425443
forward_ref_binop!(impl Add, add for Uint512, Uint512);
@@ -428,7 +446,7 @@ impl Sub<Uint512> for Uint512 {
428446
type Output = Self;
429447

430448
fn sub(self, rhs: Self) -> Self {
431-
Uint512(self.0.checked_sub(rhs.0).unwrap())
449+
self.panicking_sub(rhs)
432450
}
433451
}
434452
forward_ref_binop!(impl Sub, sub for Uint512, Uint512);
@@ -1338,6 +1356,21 @@ mod tests {
13381356
assert_eq!(a, Uint512::from(1u32));
13391357
}
13401358

1359+
#[test]
1360+
fn uint512_panicking_sub_works() {
1361+
let a = Uint512::from(5u32);
1362+
let b = Uint512::from(3u32);
1363+
assert_eq!(a.panicking_sub(b), Uint512::from(2u32));
1364+
}
1365+
1366+
#[test]
1367+
#[should_panic(expected = "attempt to subtract with overflow")]
1368+
fn uint512_panicking_sub_panics_on_overflow() {
1369+
let a = Uint512::zero();
1370+
let b = Uint512::one();
1371+
let _diff = a.panicking_sub(b);
1372+
}
1373+
13411374
#[test]
13421375
fn uint512_abs_diff_works() {
13431376
let a = Uint512::from(42u32);

packages/std/src/math/uint64.rs

+39-10
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,28 @@ impl Uint64 {
252252
Self(self.0.saturating_pow(exp))
253253
}
254254

255+
/// This is the same as [`Uint64::add`] but const.
256+
///
257+
/// Panics on overflow.
258+
#[must_use = "this returns the result of the operation, without modifying the original"]
259+
pub const fn panicking_add(self, other: Self) -> Self {
260+
match self.0.checked_add(other.u64()) {
261+
None => panic!("attempt to add with overflow"),
262+
Some(sum) => Self(sum),
263+
}
264+
}
265+
266+
/// This is the same as [`Uint64::sub`] 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_sub(self, other: Self) -> Self {
271+
match self.0.checked_sub(other.u64()) {
272+
None => panic!("attempt to subtract with overflow"),
273+
Some(diff) => Self(diff),
274+
}
275+
}
276+
255277
#[must_use = "this returns the result of the operation, without modifying the original"]
256278
pub const fn abs_diff(self, other: Self) -> Self {
257279
Self(if self.0 < other.0 {
@@ -326,11 +348,7 @@ impl Add<Uint64> for Uint64 {
326348
type Output = Self;
327349

328350
fn add(self, rhs: Self) -> Self {
329-
Self(
330-
self.u64()
331-
.checked_add(rhs.u64())
332-
.expect("attempt to add with overflow"),
333-
)
351+
self.panicking_add(rhs)
334352
}
335353
}
336354
forward_ref_binop!(impl Add, add for Uint64, Uint64);
@@ -339,11 +357,7 @@ impl Sub<Uint64> for Uint64 {
339357
type Output = Self;
340358

341359
fn sub(self, rhs: Self) -> Self {
342-
Uint64(
343-
self.u64()
344-
.checked_sub(rhs.u64())
345-
.expect("attempt to subtract with overflow"),
346-
)
360+
self.panicking_sub(rhs)
347361
}
348362
}
349363
forward_ref_binop!(impl Sub, sub for Uint64, Uint64);
@@ -1062,6 +1076,21 @@ mod tests {
10621076
assert_eq!(a, Uint64::from(1u32));
10631077
}
10641078

1079+
#[test]
1080+
fn uint64_panicking_sub_works() {
1081+
let a = Uint64::new(5);
1082+
let b = Uint64::new(3);
1083+
assert_eq!(a.panicking_sub(b), Uint64::new(2));
1084+
}
1085+
1086+
#[test]
1087+
#[should_panic(expected = "attempt to subtract with overflow")]
1088+
fn uint64_panicking_sub_panics_on_overflow() {
1089+
let a = Uint64::zero();
1090+
let b = Uint64::one();
1091+
let _diff = a.panicking_sub(b);
1092+
}
1093+
10651094
#[test]
10661095
fn uint64_abs_diff_works() {
10671096
let a = Uint64::from(42u32);

0 commit comments

Comments
 (0)