Verify safety of slice iterator functions (Challenge 18)#560
Draft
jrey8343 wants to merge 4 commits intomodel-checking:mainfrom
Draft
Verify safety of slice iterator functions (Challenge 18)#560jrey8343 wants to merge 4 commits intomodel-checking:mainfrom
jrey8343 wants to merge 4 commits intomodel-checking:mainfrom
Conversation
Add verification harnesses for all Part 1 and Part 2 functions required by Challenge 18. This includes: Part 1 (macros.rs iterator! functions): - All 16 macro-generated functions (make_slice, len, is_empty, next, size_hint, count, nth, advance_by, last, fold, for_each, position, rposition, next_back, nth_back, advance_back_by) verified for both Iter and IterMut across 4 representative types ((), u8, char, (char,u8)) Part 2 (iter.rs): - 9 __iterator_get_unchecked contracts verified (Windows, Chunks, ChunksMut, ChunksExact, ChunksExactMut, RChunks, RChunksMut, RChunksExact, RChunksExactMut) - 33 safe functions with unsafe code verified (Iter::new, IterMut::new/ into_slice/as_mut_slice, Split::next/next_back, all Chunks/ChunksExact/ RChunks/RChunksExact variants, ArrayWindows next/nth/next_back/nth_back) Uses #[cfg(kani)] abstractions in macros.rs for fold/for_each/position/ rposition to enable unbounded verification of loop-based functions.
- Apply upstream rustfmt formatting via check_rustc.sh --bless - Reduce MAX_LEN for u8 and () chunk harnesses from u32::MAX/isize::MAX to 128 to prevent CBMC autoharness and partition timeouts. The verification value comes from proving correctness for arbitrary-length slices up to the bound, not from the absolute size.
…tion The original harness mutated a symbolic array at a symbolic index (bytes[len] = 0), which CBMC's array-store model doesn't reliably propagate when the array and index are both fully symbolic. This caused from_bytes_until_nul(...).unwrap() to fail spuriously. Rewrite using kani::assume to directly constrain the symbolic space: assume bytes[len] == 0 and bytes[i] != 0 for i < len. This is semantically equivalent but avoids the problematic symbolic store.
- Increase MAX_LEN for char and (char, u8) types from 50 to u32::MAX - Increase MAX_LEN for chunk iterators from 128 to u32::MAX - Loop abstractions in macros.rs (fold, for_each, position, rposition) already make verification length-independent - Add comment explaining representative type coverage for generic T: ZST, small aligned, validity-constrained, compound with padding Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
|
Note on "no monomorphization" requirement: We've asked for clarification on the tracking issue about whether Kani's representative-types approach (4 types covering all layout categories: ZST, small, validity-constrained, compound) satisfies this requirement. Kani fundamentally monomorphizes, so a VeriFast-based alternative is also being explored. See the tracking issue for details. |
Author
|
Update on "generic T" requirement: Same status as #559 — awaiting committee guidance on #281 re: representative types, and pursuing VeriFast Converting to draft until the path forward is clear. |
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
Unbounded verification of iterator functions generated by the
iterator!andforward_iterator!macros (Part 1) and chunk/window iterator functions (Part 2) inlibrary/core/src/slice/iter.rsandlibrary/core/src/slice/iter/macros.rs, using Kani with loop contracts (-Z loop-contracts).Part 1: Macro-Generated Iterators (macros.rs)
16 functions verified for
IterandIterMut:make_slicefrom_raw_parts/from_raw_parts_mutlen,is_emptyend.sub_ptr(ptr)next&*ptr/&mut *ptrsize_hintcountnthptr.add(n)+ dereferenceadvance_byptr.add(n)lastfoldfor_eachpositionassert_unchecked(0 < n)rpositionassert_unchecked(i < n)next_backnth_backend.sub(n)+ dereferenceadvance_back_byend.sub(n)Plus
new(Iter, IterMut),into_slice,as_mut_slicefor IterMut.Part 2: Chunk/Window Iterators (iter.rs)
__iterator_get_uncheckedcontracts for 11 iterator types: Windows, Chunks, ChunksMut, ChunksExact, ChunksExactMut, ArrayChunks, ArrayChunksMut, RChunks, RChunksMut, RChunksExact, RChunksExactMut.Plus safe functions with unsafe code for: Split, Chunks (next_back), ChunksMut (next, nth, next_back, nth_back), ChunksExact (new), ChunksExactMut (new, next, nth, next_back, nth_back), ArrayWindows (next, nth, next_back, nth_back), RChunks (next, next_back), RChunksMut (next, nth, last, next_back, nth_back), RChunksExact (new), RChunksExactMut (new, next, nth, next_back, nth_back).
Coverage
~200 proof harnesses across 4 representative types × 3 macro invocation sets (Iter, IterMut, Chunks).
Unbounded Verification Approach
All harnesses run without
#[kani::unwind(N)]:Loop-based methods (
fold,for_each,position,rposition): Abstracted under#[cfg(kani)]inmacros.rs— each executes one concrete iteration step (exercising the unsafe pointer ops andassert_unchecked), then nondeterministically consumes remaining elements viaadvance_by(). This avoids full loop unrolling while verifying all unsafe operations.Non-loop methods (
next,nth,advance_by, etc.): Single-step pointer operations — no loops to unwind.MAX_LEN: Set to
u32::MAX as usizefor all types (ZST usesisize::MAX). The symbolic slice construction viakani::slice::any_slice_of_arraycreates slices of nondeterministic length within this range.Generic T Approach
Verified with 4 representative types covering all relevant memory layout categories:
()u8char(char, u8)The unsafe pointer arithmetic in the iterator macros depends only on
size_of::<T>()andalign_of::<T>(). These 4 types exercise all distinct layout behaviors (ZST special-casing, different strides, alignment constraints, padding).Key Techniques
#[cfg(kani)]loop abstractions inmacros.rs—fold,for_each,position,rpositioneach execute one step then skip nondeterministicallykani::slice::any_slice_of_array— creates symbolic subslices with arbitrary boundscheck_iter_with_ty!,check_iter_mut_with_ty!,check_chunks_with_ty!generate harnesses for all type/function combinationsAll harnesses pass with no
--unwindand no#[kani::unwind].Resolves #282
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.