Skip to content

Commit 5e95d2f

Browse files
authored
Merge pull request #595 from tpdenk/master
add missing {forward,backward}_overflowing impls
2 parents e08dcf0 + 32bd99d commit 5e95d2f

3 files changed

Lines changed: 130 additions & 0 deletions

File tree

src/addr.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,30 @@ impl Step for VirtAddr {
485485
fn backward_checked(start: Self, count: usize) -> Option<Self> {
486486
Self::backward_checked_u64(start, u64::try_from(count).ok()?)
487487
}
488+
489+
// Kani's bundled toolchain predates these methods being added to `Step`.
490+
// Exclude them there so the crate still compiles under `cargo kani`.
491+
// This can be removed once Kani upgrades its bundled toolchain to nightly-2026-07-10 or later.
492+
#[cfg(not(kani))]
493+
#[inline]
494+
fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
495+
match Self::forward_checked(start, count) {
496+
Some(next) => (next, false),
497+
None => (start, true),
498+
}
499+
}
500+
501+
// Kani's bundled toolchain predates these methods being added to `Step`.
502+
// Exclude them there so the crate still compiles under `cargo kani`.
503+
// This can be removed once Kani upgrades its bundled toolchain to nightly-2026-07-10 or later.
504+
#[cfg(not(kani))]
505+
#[inline]
506+
fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
507+
match Self::backward_checked(start, count) {
508+
Some(next) => (next, false),
509+
None => (start, true),
510+
}
511+
}
488512
}
489513

490514
#[cfg(kani)]
@@ -936,6 +960,26 @@ mod tests {
936960
);
937961
}
938962

963+
#[test]
964+
#[cfg(feature = "step_trait")]
965+
fn virtaddr_step_overflowing() {
966+
assert_eq!(
967+
Step::forward_overflowing(VirtAddr(0x7fff_ffff_ffff), 1),
968+
(VirtAddr(0xffff_8000_0000_0000), false)
969+
);
970+
assert_eq!(
971+
Step::backward_overflowing(VirtAddr(0xffff_8000_0000_0000), 1),
972+
(VirtAddr(0x7fff_ffff_ffff), false)
973+
);
974+
assert_eq!(
975+
Step::forward_overflowing(VirtAddr(0), 0),
976+
(VirtAddr(0), false)
977+
);
978+
979+
assert!(Step::forward_overflowing(VirtAddr(0xffff_ffff_ffff_ffff), 1).1);
980+
assert!(Step::backward_overflowing(VirtAddr(0), 1).1);
981+
}
982+
939983
#[test]
940984
pub fn test_align_up() {
941985
// align 1

src/structures/paging/page.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,28 @@ impl<S: PageSize> Step for Page<S> {
322322
size: PhantomData,
323323
})
324324
}
325+
326+
// Kani's bundled toolchain predates these methods being added to `Step`.
327+
// Exclude them there so the crate still compiles under `cargo kani`.
328+
// This can be removed once Kani upgrades its bundled toolchain to nightly-2026-07-10 or later.
329+
#[cfg(not(kani))]
330+
fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
331+
match Self::forward_checked(start, count) {
332+
Some(next) => (next, false),
333+
None => (start, true),
334+
}
335+
}
336+
337+
// Kani's bundled toolchain predates these methods being added to `Step`.
338+
// Exclude them there so the crate still compiles under `cargo kani`.
339+
// This can be removed once Kani upgrades its bundled toolchain to nightly-2026-07-10 or later.
340+
#[cfg(not(kani))]
341+
fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
342+
match Self::backward_checked(start, count) {
343+
Some(next) => (next, false),
344+
None => (start, true),
345+
}
346+
}
325347
}
326348

327349
/// A range of pages with exclusive upper bound.
@@ -914,6 +936,24 @@ mod tests {
914936
assert_eq!(Step::steps_between(&start, &end), (lower, upper));
915937
}
916938
}
939+
940+
#[test]
941+
#[cfg(feature = "step_trait")]
942+
fn page_step_overflowing() {
943+
let page = |addr| Page::<Size4KiB>::from_start_address(VirtAddr::new(addr)).unwrap();
944+
945+
assert_eq!(
946+
Step::forward_overflowing(page(0x7fff_ffff_f000), 1),
947+
(page(0xffff_8000_0000_0000), false)
948+
);
949+
assert_eq!(
950+
Step::backward_overflowing(page(0xffff_8000_0000_0000), 1),
951+
(page(0x7fff_ffff_f000), false)
952+
);
953+
954+
assert!(Step::forward_overflowing(page(0xffff_ffff_ffff_f000), 1).1);
955+
assert!(Step::backward_overflowing(page(0), 1).1);
956+
}
917957
}
918958

919959
#[cfg(kani)]

src/structures/paging/page_table.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,30 @@ impl Step for PageTableIndex {
388388
let idx = usize::from(start).checked_sub(count)?;
389389
Some(Self::new(idx as u16))
390390
}
391+
392+
// Kani's bundled toolchain predates these methods being added to `Step`.
393+
// Exclude them there so the crate still compiles under `cargo kani`.
394+
// This can be removed once Kani upgrades its bundled toolchain to nightly-2026-07-10 or later.
395+
#[cfg(not(kani))]
396+
#[inline]
397+
fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
398+
match Self::forward_checked(start, count) {
399+
Some(next) => (next, false),
400+
None => (start, true),
401+
}
402+
}
403+
404+
// Kani's bundled toolchain predates these methods being added to `Step`.
405+
// Exclude them there so the crate still compiles under `cargo kani`.
406+
// This can be removed once Kani upgrades its bundled toolchain to nightly-2026-07-10 or later.
407+
#[cfg(not(kani))]
408+
#[inline]
409+
fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
410+
match Self::backward_checked(start, count) {
411+
Some(next) => (next, false),
412+
None => (start, true),
413+
}
414+
}
391415
}
392416

393417
/// A 12-bit offset into a 4KiB Page.
@@ -485,3 +509,25 @@ impl PageTableLevel {
485509
1u64 << (((self as u8 - 1) * 9) + 12)
486510
}
487511
}
512+
513+
#[cfg(all(test, feature = "step_trait"))]
514+
mod tests {
515+
use super::*;
516+
use core::iter::Step;
517+
518+
#[test]
519+
fn page_table_index_step_overflowing() {
520+
assert_eq!(
521+
Step::forward_overflowing(PageTableIndex::new(0), 511),
522+
(PageTableIndex::new(511), false)
523+
);
524+
assert_eq!(
525+
Step::backward_overflowing(PageTableIndex::new(511), 511),
526+
(PageTableIndex::new(0), false)
527+
);
528+
529+
// Overflow the 0..512 range: only the flag is specified.
530+
assert!(Step::forward_overflowing(PageTableIndex::new(511), 1).1);
531+
assert!(Step::backward_overflowing(PageTableIndex::new(0), 1).1);
532+
}
533+
}

0 commit comments

Comments
 (0)