Skip to content

Commit ca7ba2b

Browse files
jrey8343claude
andcommitted
Add remaining Ch17/Ch18 harnesses: as_chunks_unchecked, get_disjoint, fold/for_each/position
Ch17 additions (25 total harnesses in mod.rs): - as_chunks_unchecked, as_chunks_unchecked_mut (N=1,2,4) - get_disjoint_mut (N=2,3), get_disjoint_unchecked_mut (N=2) Ch18 additions (52 total harnesses in iter.rs): - __iterator_get_unchecked for ChunksMut, ChunksExact, RChunks, RChunksMut, RChunksExact, RChunksExactMut - Macro functions: fold, for_each, position, rposition (Iter) - Macro functions: fold, for_each, position (IterMut) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 547924c commit ca7ba2b

2 files changed

Lines changed: 238 additions & 0 deletions

File tree

library/core/src/slice/iter.rs

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3837,4 +3837,153 @@ mod verify {
38373837
}
38383838
}
38393839
}
3840+
3841+
// --- __iterator_get_unchecked for remaining iterator types ---
3842+
mod verify_get_unchecked {
3843+
use super::*;
3844+
3845+
#[kani::proof]
3846+
fn check_chunks_mut_get_unchecked() {
3847+
let mut array: [u8; 64] = kani::any();
3848+
let slice = any_slice_mut(&mut array);
3849+
let len = slice.len();
3850+
if len > 0 {
3851+
let chunk_size: usize = kani::any_where(|s: &usize| *s > 0 && *s <= 64);
3852+
let chunks = slice.chunks_mut(chunk_size);
3853+
if chunks.len() > 0 {
3854+
let idx: usize = kani::any_where(|i: &usize| *i < chunks.len());
3855+
let _ = unsafe { chunks.__iterator_get_unchecked(idx) };
3856+
}
3857+
}
3858+
}
3859+
3860+
#[kani::proof]
3861+
fn check_chunks_exact_get_unchecked() {
3862+
let array: [u8; 64] = kani::any();
3863+
let slice = any_slice(&array);
3864+
let chunk_size: usize = kani::any_where(|s: &usize| *s > 0 && *s <= 64);
3865+
let chunks = slice.chunks_exact(chunk_size);
3866+
if chunks.len() > 0 {
3867+
let idx: usize = kani::any_where(|i: &usize| *i < chunks.len());
3868+
let _ = unsafe { chunks.__iterator_get_unchecked(idx) };
3869+
}
3870+
}
3871+
3872+
#[kani::proof]
3873+
fn check_rchunks_get_unchecked() {
3874+
let array: [u8; 64] = kani::any();
3875+
let slice = any_slice(&array);
3876+
let chunk_size: usize = kani::any_where(|s: &usize| *s > 0 && *s <= 64);
3877+
let rchunks = slice.rchunks(chunk_size);
3878+
if rchunks.len() > 0 {
3879+
let idx: usize = kani::any_where(|i: &usize| *i < rchunks.len());
3880+
let _ = unsafe { rchunks.__iterator_get_unchecked(idx) };
3881+
}
3882+
}
3883+
3884+
#[kani::proof]
3885+
fn check_rchunks_mut_get_unchecked() {
3886+
let mut array: [u8; 64] = kani::any();
3887+
let slice = any_slice_mut(&mut array);
3888+
let len = slice.len();
3889+
if len > 0 {
3890+
let chunk_size: usize = kani::any_where(|s: &usize| *s > 0 && *s <= 64);
3891+
let rchunks = slice.rchunks_mut(chunk_size);
3892+
if rchunks.len() > 0 {
3893+
let idx: usize = kani::any_where(|i: &usize| *i < rchunks.len());
3894+
let _ = unsafe { rchunks.__iterator_get_unchecked(idx) };
3895+
}
3896+
}
3897+
}
3898+
3899+
#[kani::proof]
3900+
fn check_rchunks_exact_get_unchecked() {
3901+
let array: [u8; 64] = kani::any();
3902+
let slice = any_slice(&array);
3903+
let chunk_size: usize = kani::any_where(|s: &usize| *s > 0 && *s <= 64);
3904+
let rchunks = slice.rchunks_exact(chunk_size);
3905+
if rchunks.len() > 0 {
3906+
let idx: usize = kani::any_where(|i: &usize| *i < rchunks.len());
3907+
let _ = unsafe { rchunks.__iterator_get_unchecked(idx) };
3908+
}
3909+
}
3910+
3911+
#[kani::proof]
3912+
fn check_rchunks_exact_mut_get_unchecked() {
3913+
let mut array: [u8; 64] = kani::any();
3914+
let slice = any_slice_mut(&mut array);
3915+
let len = slice.len();
3916+
if len > 0 {
3917+
let chunk_size: usize = kani::any_where(|s: &usize| *s > 0 && *s <= 64);
3918+
let rchunks = slice.rchunks_exact_mut(chunk_size);
3919+
if rchunks.len() > 0 {
3920+
let idx: usize = kani::any_where(|i: &usize| *i < rchunks.len());
3921+
let _ = unsafe { rchunks.__iterator_get_unchecked(idx) };
3922+
}
3923+
}
3924+
}
3925+
}
3926+
3927+
// --- Macro-generated functions: fold, for_each, position, rposition ---
3928+
mod verify_macro_fns {
3929+
use super::*;
3930+
3931+
#[kani::proof]
3932+
fn check_iter_fold() {
3933+
let array: [u8; 16] = kani::any();
3934+
let iter = any_iter(&array);
3935+
let sum = iter.fold(0u32, |acc, &x| acc.wrapping_add(x as u32));
3936+
let _ = sum;
3937+
}
3938+
3939+
#[kani::proof]
3940+
fn check_iter_for_each() {
3941+
let array: [u8; 16] = kani::any();
3942+
let iter = any_iter(&array);
3943+
let mut count = 0usize;
3944+
iter.for_each(|_| count += 1);
3945+
}
3946+
3947+
#[kani::proof]
3948+
fn check_iter_position() {
3949+
let array: [u8; 16] = kani::any();
3950+
let iter = any_iter(&array);
3951+
let target: u8 = kani::any();
3952+
let _ = iter.position(|x| *x == target);
3953+
}
3954+
3955+
#[kani::proof]
3956+
fn check_iter_rposition() {
3957+
let array: [u8; 16] = kani::any();
3958+
let iter = any_iter(&array);
3959+
let target: u8 = kani::any();
3960+
let _ = iter.rposition(|x| *x == target);
3961+
}
3962+
3963+
// IterMut variants
3964+
#[kani::proof]
3965+
fn check_iter_mut_fold() {
3966+
let mut array: [u8; 16] = kani::any();
3967+
let slice = any_slice_mut(&mut array);
3968+
let iter = slice.iter_mut();
3969+
let sum = iter.fold(0u32, |acc, x| acc.wrapping_add(*x as u32));
3970+
let _ = sum;
3971+
}
3972+
3973+
#[kani::proof]
3974+
fn check_iter_mut_for_each() {
3975+
let mut array: [u8; 16] = kani::any();
3976+
let slice = any_slice_mut(&mut array);
3977+
let mut iter = slice.iter_mut();
3978+
iter.for_each(|x| *x = 0);
3979+
}
3980+
3981+
#[kani::proof]
3982+
fn check_iter_mut_position() {
3983+
let mut array: [u8; 16] = kani::any();
3984+
let slice = any_slice_mut(&mut array);
3985+
let target: u8 = kani::any();
3986+
let _ = slice.iter_mut().position(|x| *x == target);
3987+
}
3988+
}
38403989
}

library/core/src/slice/mod.rs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5833,4 +5833,93 @@ mod verify {
58335833
slice.copy_within(src_start..src_end, dest);
58345834
}
58355835
}
5836+
5837+
// --- as_chunks_unchecked / as_chunks_unchecked_mut ---
5838+
macro_rules! check_as_chunks_unchecked {
5839+
($name:ident, $N:expr) => {
5840+
#[kani::proof]
5841+
fn $name() {
5842+
const ARR_SIZE: usize = 64;
5843+
let arr: [u8; ARR_SIZE] = kani::any();
5844+
let slice = kani::slice::any_slice_of_array(&arr);
5845+
// Only call when len is a multiple of N
5846+
if slice.len() > 0 && slice.len() % $N == 0 {
5847+
let chunks = unsafe { slice.as_chunks_unchecked::<$N>() };
5848+
assert!(chunks.len() == slice.len() / $N);
5849+
}
5850+
}
5851+
};
5852+
}
5853+
check_as_chunks_unchecked!(check_as_chunks_unchecked_1, 1);
5854+
check_as_chunks_unchecked!(check_as_chunks_unchecked_2, 2);
5855+
check_as_chunks_unchecked!(check_as_chunks_unchecked_4, 4);
5856+
5857+
macro_rules! check_as_chunks_unchecked_mut {
5858+
($name:ident, $N:expr) => {
5859+
#[kani::proof]
5860+
fn $name() {
5861+
const ARR_SIZE: usize = 64;
5862+
let mut arr: [u8; ARR_SIZE] = kani::any();
5863+
let slice = kani::slice::any_slice_of_array_mut(&mut arr);
5864+
let len = slice.len();
5865+
if len > 0 && len % $N == 0 {
5866+
let chunks = unsafe { slice.as_chunks_unchecked_mut::<$N>() };
5867+
assert!(chunks.len() == len / $N);
5868+
}
5869+
}
5870+
};
5871+
}
5872+
check_as_chunks_unchecked_mut!(check_as_chunks_unchecked_mut_1, 1);
5873+
check_as_chunks_unchecked_mut!(check_as_chunks_unchecked_mut_2, 2);
5874+
check_as_chunks_unchecked_mut!(check_as_chunks_unchecked_mut_4, 4);
5875+
5876+
// --- get_disjoint_mut / get_disjoint_unchecked_mut ---
5877+
#[kani::proof]
5878+
fn check_get_disjoint_mut_2() {
5879+
let mut arr: [u8; 16] = kani::any();
5880+
let slice = kani::slice::any_slice_of_array_mut(&mut arr);
5881+
let len = slice.len();
5882+
if len >= 2 {
5883+
let i: usize = kani::any();
5884+
let j: usize = kani::any();
5885+
kani::assume(i < len);
5886+
kani::assume(j < len);
5887+
kani::assume(i != j);
5888+
let result = slice.get_disjoint_mut([i, j]);
5889+
assert!(result.is_ok());
5890+
}
5891+
}
5892+
5893+
#[kani::proof]
5894+
fn check_get_disjoint_unchecked_mut_2() {
5895+
let mut arr: [u8; 16] = kani::any();
5896+
let slice = kani::slice::any_slice_of_array_mut(&mut arr);
5897+
let len = slice.len();
5898+
if len >= 2 {
5899+
let i: usize = kani::any();
5900+
let j: usize = kani::any();
5901+
kani::assume(i < len);
5902+
kani::assume(j < len);
5903+
kani::assume(i != j);
5904+
let [a, b] = unsafe { slice.get_disjoint_unchecked_mut([i, j]) };
5905+
*a = 42;
5906+
*b = 99;
5907+
}
5908+
}
5909+
5910+
#[kani::proof]
5911+
fn check_get_disjoint_mut_3() {
5912+
let mut arr: [u8; 16] = kani::any();
5913+
let slice = kani::slice::any_slice_of_array_mut(&mut arr);
5914+
let len = slice.len();
5915+
if len >= 3 {
5916+
let i: usize = kani::any();
5917+
let j: usize = kani::any();
5918+
let k: usize = kani::any();
5919+
kani::assume(i < len && j < len && k < len);
5920+
kani::assume(i != j && i != k && j != k);
5921+
let result = slice.get_disjoint_mut([i, j, k]);
5922+
assert!(result.is_ok());
5923+
}
5924+
}
58365925
}

0 commit comments

Comments
 (0)