Challenge 16: Verify safety of iterator adapter functions with Kani - #632
Draft
v3risec wants to merge 1 commit into
Draft
Challenge 16: Verify safety of iterator adapter functions with Kani#632v3risec wants to merge 1 commit into
v3risec wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds Kani-based verification for Challenge 16, covering the iterator safety targets in
library/core/src/iter/adapters.The change introduces:
array_chunks.rs,skip.rs,take.rs, andzip.rsbool, zero-sized types, and arraysAll verification-only modules and annotations are gated by
cfg(kani). Normal non-Kani builds retain their existing runtime behavior.Challenge Coverage
Unsafe functions
The following unsafe functions receive safety contracts and proof coverage:
Cloned::__iterator_get_uncheckedCloned::next_uncheckedCopied::__iterator_get_uncheckedEnumerate::__iterator_get_uncheckedFuse::__iterator_get_uncheckedMap::__iterator_get_uncheckedMap::next_uncheckedSkip::__iterator_get_uncheckedZip::__iterator_get_uncheckedZipImpl::get_uncheckedThe challenge refers to
clone.rs; the corresponding file in the current source tree iscloned.rs.Because Kani's contract harness machinery cannot resolve several specialized trait-method paths, the proofs call those implementations through explicit trait paths and establish their preconditions with
kani::assume.Safe functions
Proof harnesses cover all safe abstractions listed by the challenge:
ArrayChunks::next_back_remainderArrayChunks::foldCopied::spec_next_chunkFilter::next_chunk_droplessFilterMap::next_chunkBuffer::as_array_refBuffer::as_uninit_array_mutBuffer::pushBuffer::dropStepBy::original_stepTake::spec_foldTake::spec_for_eachZip::foldZip::nextZip::nthZip::next_backZip::spec_foldVerification Approach
The proofs use a combination of:
Symbolic iterator states
Random-access adapter proofs use symbolic lengths, indices, pending skip counts, zip offsets, and payload values. Lazy ranges and mapped ranges allow many of these proofs to avoid imposing a harness-level length bound.
Safety contracts
The unsafe functions require the requested element to be within the trusted lower bound or remaining iterator size. The
Fusecontract additionally requires the inner iterator to remain present.Loop contracts
Loop invariants preserve the index and iterator-size relationships needed by unchecked accesses in
ArrayChunks,Skip,Take, andZip.Specialization-aware harnesses
The harnesses construct iterators implementing the required
TrustedRandomAccess,TrustedRandomAccessNoCoerce, orTrustedLenbounds and call the specialized implementation directly where necessary.Representative concrete types
The proofs instantiate the adapters with signed and unsigned integer widths,
bool,(), and[u8; 4].MapWindowsadditionally exercises multiple window sizes.Kani checks the resulting programs for invalid pointer accesses, uninitialized reads, mutation through invalid references, invalid values, arithmetic failures, and assertion violations.
Notes
Generic type requirement: Kani verifies concrete monomorphized programs. This branch therefore uses representative concrete types rather than providing a single non-monomorphized proof for arbitrary
T.Const-generic coverage: Chunk and window operations are exercised with representative values of
N, rather than universally quantifying over every nonzero const-generic value.Zip::spec_fold: Undercfg(kani), the originalTrustedLenloop is represented by a sound loop abstraction that nondeterministically selects an arbitrary valid iteration. Because the selected index is unconstrained within the entire range, the proof covers every possible iteration rather than only a fixed prefix. TheTrustedLeninvariant guarantees that both iterators contain an element at that position, so verifying the correspondingunwrap_uncheckedcalls establishes their safety for all loop iterations without explicitly unwinding the full loop.Verification
All added Challenge 21 harnesses pass locally with Kani.
Resolves #280
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.