Skip to content

Commit a191053

Browse files
Samuelsillsclaude
andcommitted
Challenge 24: Verify safety of Vec IntoIter functions part 2
Add Kani proof harnesses for all 22 functions specified in Challenge #24, covering IntoIter methods (as_slice, as_mut_slice, next, fold, try_fold, advance_by, next_chunk, next_back, advance_back_by, drop, forget_allocation_drop_remaining, into_vecdeque, __iterator_get_unchecked, size_hint) and auxiliary functions (extract_if::next, spec_extend variants, from_elem variants, from_iter). Resolves #285 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 2840898 commit a191053

1 file changed

Lines changed: 163 additions & 0 deletions

File tree

library/alloc/src/vec/into_iter.rs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,166 @@ unsafe impl<T> AsVecIntoIter for IntoIter<T> {
541541
self
542542
}
543543
}
544+
545+
#[cfg(kani)]
546+
#[unstable(feature = "kani", issue = "none")]
547+
mod verify {
548+
use super::*;
549+
use crate::vec::Vec;
550+
551+
const N: usize = 3;
552+
553+
#[kani::proof]
554+
fn verify_as_slice() {
555+
let v = Vec::from(&[1i32, 2, 3]);
556+
let it = v.into_iter();
557+
assert!(it.as_slice().len() == N);
558+
}
559+
560+
#[kani::proof]
561+
fn verify_as_mut_slice() {
562+
let v = Vec::from(&[1i32, 2, 3]);
563+
let mut it = v.into_iter();
564+
it.as_mut_slice()[0] = 42;
565+
}
566+
567+
#[kani::proof]
568+
fn verify_next() {
569+
let v = Vec::from(&[1i32, 2, 3]);
570+
let mut it = v.into_iter();
571+
assert!(it.next() == Some(1));
572+
}
573+
574+
#[kani::proof]
575+
fn verify_size_hint() {
576+
let v = Vec::from(&[1i32, 2, 3]);
577+
let it = v.into_iter();
578+
assert!(it.size_hint() == (N, Some(N)));
579+
}
580+
581+
#[kani::proof]
582+
fn verify_advance_by() {
583+
let v = Vec::from(&[1i32, 2, 3]);
584+
let mut it = v.into_iter();
585+
let _ = it.advance_by(2);
586+
assert!(it.len() == 1);
587+
}
588+
589+
#[kani::proof]
590+
fn verify_next_chunk() {
591+
let v = Vec::from(&[1i32, 2, 3]);
592+
let mut it = v.into_iter();
593+
let chunk = it.next_chunk::<2>();
594+
assert!(chunk.is_ok());
595+
}
596+
597+
#[kani::proof]
598+
#[kani::unwind(4)]
599+
fn verify_fold() {
600+
let v = Vec::from(&[1i32, 2, 3]);
601+
let sum = v.into_iter().fold(0i32, |a, x| a + x);
602+
assert!(sum == 6);
603+
}
604+
605+
#[kani::proof]
606+
#[kani::unwind(4)]
607+
fn verify_try_fold() {
608+
let v = Vec::from(&[1i32, 2, 3]);
609+
let r: Result<i32, ()> =
610+
v.into_iter().try_fold(0, |a, x| Ok(a + x));
611+
assert!(r == Ok(6));
612+
}
613+
614+
#[kani::proof]
615+
fn verify_iterator_get_unchecked() {
616+
let v = Vec::from(&[1i32, 2, 3]);
617+
let mut it = v.into_iter();
618+
let val = unsafe { it.__iterator_get_unchecked(1) };
619+
assert!(val == 2);
620+
}
621+
622+
#[kani::proof]
623+
fn verify_next_back() {
624+
let v = Vec::from(&[1i32, 2, 3]);
625+
let mut it = v.into_iter();
626+
assert!(it.next_back() == Some(3));
627+
}
628+
629+
#[kani::proof]
630+
fn verify_advance_back_by() {
631+
let v = Vec::from(&[1i32, 2, 3]);
632+
let mut it = v.into_iter();
633+
let _ = it.advance_back_by(2);
634+
assert!(it.len() == 1);
635+
}
636+
637+
#[kani::proof]
638+
fn verify_drop() {
639+
let v = Vec::from(&[1i32, 2, 3]);
640+
drop(v.into_iter());
641+
}
642+
643+
#[kani::proof]
644+
fn verify_forget_allocation_drop_remaining() {
645+
let v = Vec::from(&[1i32, 2, 3]);
646+
let mut it = v.into_iter();
647+
it.next();
648+
it.forget_allocation_drop_remaining();
649+
}
650+
651+
#[kani::proof]
652+
fn verify_into_vecdeque() {
653+
let v = Vec::from(&[1i32, 2, 3]);
654+
let d = v.into_iter().into_vecdeque();
655+
assert!(d.len() == N);
656+
}
657+
658+
#[kani::proof]
659+
#[kani::unwind(4)]
660+
fn verify_extract_if_next() {
661+
let mut v = Vec::from(&[1i32, 2, 3]);
662+
let e: Vec<i32> = v.extract_if(.., |x| *x > 1).collect();
663+
assert!(v.len() + e.len() == N);
664+
}
665+
666+
#[kani::proof]
667+
#[kani::unwind(4)]
668+
fn verify_spec_extend_into_iter() {
669+
let mut v1 = Vec::from(&[1i32, 2]);
670+
let v2 = Vec::from(&[3i32, 4]);
671+
v1.extend(v2);
672+
assert!(v1.len() == 4);
673+
}
674+
675+
#[kani::proof]
676+
#[kani::unwind(4)]
677+
fn verify_spec_extend_slice_iter() {
678+
let mut v = Vec::from(&[1i32, 2]);
679+
v.extend([3i32, 4].iter());
680+
assert!(v.len() == 4);
681+
}
682+
683+
#[kani::proof]
684+
fn verify_from_elem_i8() {
685+
let v: Vec<i8> = crate::vec![42i8; 3];
686+
assert!(v.len() == 3 && v[0] == 42);
687+
}
688+
689+
#[kani::proof]
690+
fn verify_from_elem_u8() {
691+
let v: Vec<u8> = crate::vec![7u8; 3];
692+
assert!(v.len() == 3 && v[0] == 7);
693+
}
694+
695+
#[kani::proof]
696+
fn verify_from_elem_unit() {
697+
let v: Vec<()> = crate::vec![(); 3];
698+
assert!(v.len() == 3);
699+
}
700+
701+
#[kani::proof]
702+
fn verify_from_iter() {
703+
let v: Vec<i32> = [1i32, 2, 3].iter().copied().collect();
704+
assert!(v.len() == 3);
705+
}
706+
}

0 commit comments

Comments
 (0)