Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/check-semantic-versioning.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ jobs:
# If we don't explicitly set which features to check `const_convert_and_const_trait_impl` will be used,
# which fails on modern compilers (which cargo-semver-checks requires).
# also, quickcheck was broken in 2.0.0, so we don't want that either.
# step_trait is excluded: it is nightly-only, and its `Step` impl tracks the
# current nightly `Step` trait, which doesn't compile on the stable toolchain
# this check runs on.
feature-group: "only-explicit-features"
features: "std,step_trait,defmt,serde,borsh,schemars,arbitrary,num-traits"
features: "std,defmt,serde,borsh,schemars,arbitrary,num-traits"
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## Unreleased

### Fixed

- Implemented `Step::forward_overflowing()` and `Step::backward_overflowing()`, which are new required
methods of the unstable `Step` trait ([rust#155114]).

[rust#155114]: https://github.com/rust-lang/rust/pull/155114

## 2.1.1

### Added
Expand Down
12 changes: 12 additions & 0 deletions src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,18 @@ macro_rules! impl_step {
None
}
}

#[inline]
fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
let (res, overflow) = core::iter::Step::forward_overflowing(start.value, count);
(Self::masked_new(res), overflow || res > Self::MAX.value)
}

#[inline]
fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
let (res, overflow) = core::iter::Step::backward_overflowing(start.value, count);
(Self::masked_new(res), overflow || res < Self::MIN.value)
}
}
};
}
Expand Down
86 changes: 86 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3575,6 +3575,92 @@ fn backward_checked_signed() {
assert_eq!(None, Step::backward_checked(i7::new(-64), 65));
}

#[cfg(feature = "step_trait")]
#[test]
fn forward_overflowing_unsigned() {
// In range
assert_eq!(
(u7::new(121), false),
Step::forward_overflowing(u7::new(120), 1)
);
assert_eq!(
(u7::new(127), false),
Step::forward_overflowing(u7::new(120), 7)
);

// Out of range: the value is unspecified
assert!(Step::forward_overflowing(u7::new(120), 8).1);

// Out of range for the underlying type
assert!(Step::forward_overflowing(u7::new(120), 140).1);
}

#[cfg(feature = "step_trait")]
#[test]
fn forward_overflowing_signed() {
// In range
assert_eq!(
(i7::new(61), false),
Step::forward_overflowing(i7::new(60), 1)
);
assert_eq!(
(i7::new(63), false),
Step::forward_overflowing(i7::new(56), 7)
);
assert_eq!(
(i7::new(-60), false),
Step::forward_overflowing(i7::new(-64), 4)
);

// Out of range: the value is unspecified
assert!(Step::forward_overflowing(i7::new(60), 8).1);

// Out of range for the underlying type
assert!(Step::forward_overflowing(i7::new(60), 140).1);
}

#[cfg(feature = "step_trait")]
#[test]
fn backward_overflowing_unsigned() {
// In range
assert_eq!(
(u7::new(1), false),
Step::backward_overflowing(u7::new(10), 9)
);
assert_eq!(
(u7::new(0), false),
Step::backward_overflowing(u7::new(10), 10)
);

// Out of range: the value is unspecified
assert!(Step::backward_overflowing(u7::new(10), 11).1);
}

#[cfg(feature = "step_trait")]
#[test]
fn backward_overflowing_signed() {
// In range
assert_eq!(
(i7::new(1), false),
Step::backward_overflowing(i7::new(10), 9)
);
assert_eq!(
(i7::new(-10), false),
Step::backward_overflowing(i7::new(10), 20)
);
assert_eq!(
(i7::new(-64), false),
Step::backward_overflowing(i7::new(-60), 4)
);

// Out of range: the value is unspecified
assert!(Step::backward_overflowing(i7::new(-64), 1).1);
assert!(Step::backward_overflowing(i7::new(5), 70).1);

// Out of range for the underlying type
assert!(Step::backward_overflowing(i7::new(0), 129).1);
}

#[cfg(feature = "step_trait")]
#[test]
fn steps_between_unsigned() {
Expand Down
Loading