Skip to content

Commit 10904f0

Browse files
committed
Add loop contracts and harness for Utf8Chunk::next
1 parent c738450 commit 10904f0

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@
230230
#![feature(unboxed_closures)]
231231
#![feature(unsized_fn_params)]
232232
#![feature(with_negative_coherence)]
233+
#![feature(proc_macro_hygiene)]
233234
// tidy-alphabetical-end
234235
//
235236
// Target features:

library/core/src/str/lossy.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ use crate::fmt;
44
use crate::fmt::{Formatter, Write};
55
use crate::iter::FusedIterator;
66

7+
#[cfg(kani)]
8+
use crate::kani;
9+
710
impl [u8] {
811
/// Creates an iterator over the contiguous valid UTF-8 ranges of this
912
/// slice, and the non-UTF-8 fragments in between.
@@ -204,6 +207,11 @@ impl<'a> Iterator for Utf8Chunks<'a> {
204207

205208
let mut i = 0;
206209
let mut valid_up_to = 0;
210+
// TODO: remove `LEN` and use `self.source.len()` directly once
211+
// fix the issue that Kani loop contracts doesn't support `self`.
212+
#[cfg(kani)]
213+
let LEN = self.source.len();
214+
#[safety::loop_invariant(i <= LEN && valid_up_to == i)]
207215
while i < self.source.len() {
208216
// SAFETY: `i < self.source.len()` per previous line.
209217
// For some reason the following are both significantly slower:
@@ -296,3 +304,22 @@ impl fmt::Debug for Utf8Chunks<'_> {
296304
f.debug_struct("Utf8Chunks").field("source", &self.debug()).finish()
297305
}
298306
}
307+
308+
#[cfg(kani)]
309+
#[unstable(feature = "kani", issue = "none")]
310+
pub mod verify {
311+
use super::*;
312+
313+
#[kani::proof]
314+
pub fn check_next() {
315+
// TODO: ARR_SIZE can be `std::usize::MAX` with cbmc argument
316+
// `--arrays-uf-always`
317+
const ARR_SIZE: usize = 1000;
318+
let mut x: [u8; ARR_SIZE] = kani::any();
319+
let mut xs = kani::slice::any_slice_of_array_mut(&mut x);
320+
let mut chunks = xs.utf8_chunks();
321+
unsafe {
322+
chunks.next();
323+
}
324+
}
325+
}

scripts/run-kani.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ main() {
183183

184184
echo "Running Kani verify-std command..."
185185

186-
"$kani_path" verify-std -Z unstable-options ./library --target-dir "$temp_dir_target" -Z function-contracts -Z mem-predicates --output-format=terse $command_args
186+
"$kani_path" verify-std -Z unstable-options ./library --target-dir "$temp_dir_target" -Z function-contracts -Z mem-predicates -Z loop-contracts --output-format=terse $command_args --enable-unstable --cbmc-args --object-bits 12
187187
}
188188

189189
main

tool_config/kani-version.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
# incompatible with the verify-std repo.
33

44
[kani]
5-
commit = "2565ef65767a696f1d519b42621b4e502e8970d0"
5+
commit = "8400296f5280be4f99820129bc66447e8dff63f4"

0 commit comments

Comments
 (0)