Conversation
This branch has not been deployed
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.
Towards #279.
Kani harnesses for Challenge 22: Verify the safety of
striter functions: the 15 safe functions with unsafe code incore::str::iter(Chars,SplitInternal,MatchesInternal,MatchIndicesInternal,SplitAsciiWhitespace), plus theBytes::__iterator_get_uncheckedsafety contract. It adds 30 harnesses in a new#[cfg(kani)] mod verify. All additions are#[cfg(kani)]-gated, so non-Kani builds are unchanged; the harnesses run the real shipped bodies (no#[cfg(kani)]rewrites), and all pass viascripts/run-kani.sh.The challenge lets us assume
slice,str::pattern, andstr::validations(assumptions 1–3), and that every iterator comes from valid UTF-8 (4). The pattern searchers are therefore modeled by spec-cited stubs at their call sites, so these proofs don't re-verify thestr::patterninternals (Challenges 20/21).Chars::advance_byruns over a symbolicstrof arbitrary length but a bounded skip count (a justified unwind of its chunk loop), so the count is not literally unbounded. As with the other unbounded-verification challenges, that is left to the committee and noted under Limitations.Success criteria
__iterator_get_unchecked: write and prove the contractproof_for_contract. The#[requires(idx < self.0.len())]contract already exists in main (core/src/str/iter.rs); this proves it.kani::any()length (not a fixed array), capped only at ~2^40, the--object-bits 12offset budget. Whether a capped symbolic length counts as "arbitrary", as opposed to an uncapped loop contract, is the open committee question shared across the unbounded-verification challenges (see Limitations).advance_byalso caps its skip count.What the harnesses check
verifymodule and one kani-gatedfeature(str_split_remainder, str_split_whitespace_remainder)line inalloc/src/lib.rs(those methods are unstable). Symbolic inputs sit on zeroed backing (alloc_zeroed), valid UTF-8 by construction, which is why the module lives inalloc::str.SplitInternal, 7Matches/MatchIndices, base and advanced-state) stub the searchers at their call sites under assumption 2. A stub returns any range that is in-bounds, on UTF-8 boundaries, and monotonic: a superset of the real searcher's outputs, so no-UB under the stub gives no-UB for the real searcher. The boundary alignment is assumption 2's grant, not something the caller derives.Chars::nextandnext_backare proven jointly over arbitrary length and arbitrary valid-UTF-8 content (hybrid prefix/suffix, both ends); the one coupling is that a width-wend char needs length ≥w.Upstream
The two loop-contract gaps behind
advance_by's bounded count are ones we filed: kani#4893 (a loop inside a called combinator has no attach site) and kani#4943 (#[kani::loop_invariant]on awhilelet-chain fails to compile).Limitations
advance_byskip count is unwind-bounded; thestrlength stays symbolic. A loop invariant on the chunk-skip loop hits two walls today: its per-chunk.sum()is a combinator fold with no attach site (kani#4893), and#[kani::loop_invariant]on the loop'swhile … && letlet-chain fails to compile (kani#4943), so neither fix alone would close it. Same gate as the other unbounded-verification challenges.kani::any()capped only at ~2^40 (the--object-bits 12offset budget), not a fixed array. No concrete length is assumed.SplitInternal/MatchesInternalfields are private tocore, so an arbitrary post-k-call state would need a shipped-code change this diff avoids. The safety obligation depends on current field values, not the call count, so depth 1–2 exercises the same shape as a deeper state.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.