Challenge 17: Verify slice safety with Kani - #657
Open
v3risec wants to merge 5 commits into
Open
Conversation
v3risec
force-pushed
the
challenge-17-slice
branch
from
August 27, 2026 09:31
4b028ca to
14a278f
Compare
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 safety verification for the slice APIs listed in Challenge 17.
The changes provide:
SliceIndex<[T]>implementationGetDisjointMutIndeximplementationsreverse,binary_search_by,partition_dedup_by, and the pointer-swap loops reached by slice operationsVerification-only helpers and harnesses are gated by
cfg(kani). The standard library runtime algorithms are not replaced by Kani-specific implementations.Challenge Coverage
The existing
align_to,align_to_mut, andreverseverification is retained and included in the coverage above.Verification Approach
Contracts and frame conditions
Semantic contract annotations follow the repository-wide
safetycontract style:requiresexpresses documented caller obligations,ensurescaptures the existingalign_to{,_mut}postconditions, andsafety::loop_invariantstates the safety relationships preserved by loops. Kani-specificmodifiesandloop_modifiesannotations are used only for frame conditions, making explicit which slices, pointer regions, and loop-local state may change. This keeps semantic safety conditions separate from verifier-specific memory framing while retaining the real standard-library implementations.Harness and type coverage
Unsafe functions are connected directly to their contracts with
#[kani::proof_for_contract], so Kani verifies their real bodies under the declared preconditions and checks their postconditions. Safe abstractions use#[kani::proof]harnesses, including dedicated panic-path harnesses where applicable. The harness matrix coversi8throughi128,u8throughu128,bool,char,(), and[u8; 4], exercising different widths, alignments, validity constraints, ZST behavior, and aggregate layouts. Index-generic proofs cover every currentSliceIndex<[T]>implementation, includingusize,IndexRange, legacy and new range types, bound pairs,Clamp,Last, and exhausted legacyRangeInclusivestates. The disjoint-index proofs additionally cover all five currentGetDisjointMutIndeximplementations.Unsafe contracts
The contracts express the documented caller obligations for:
get_uncheckedandget_unchecked_mutswap_uncheckedas_chunks_uncheckedandas_chunks_unchecked_mutsplit_at_uncheckedandsplit_at_mut_uncheckedalign_toandalign_to_mutget_disjoint_unchecked_mutget_uncheckedandget_unchecked_mutuse a Kani-onlykani_in_boundspredicate on the sealedSliceIndextrait. Every current implementation provides its exact bounds condition, including legacy and new range APIs, bound pairs,Clamp,Last, and exhausted legacyRangeInclusivestates.get_disjoint_unchecked_mutuses the same complete bounds-and-overlap check as the safe API. Its contract and safe harnesses coverusize,ops::{Range, RangeInclusive}, andrange::{Range, RangeInclusive}.Loop contracts
The loop invariants preserve the index and pointer relationships required by unchecked accesses in
reverse,binary_search_by, andpartition_dedup_by.The original loops remain in place. Kani-only local declarations make per-iteration temporary values available to loop frame conditions without replacing the algorithms or their control flow.
Rotation
rotate_leftandrotate_rightcall the realptr_rotateimplementation.Separate harnesses cover:
The non-ZST configurations use fixed lengths and rotation amounts because a single symbolic harness covering all nested rotate paths did not complete in practice.
Notes
T.N.partition_dedup_by<()>is disabled because CBMC cannot register a zero-byte slice in the loop write set.swap_unchecked<()>uses a plain proof with the same documented preconditions because the contract write-set machinery has the same zero-byte-region limitation.Verification
All added Challenge 17 harnesses pass locally with Kani.
Resolves #281
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.