Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions library/kani/src/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,51 @@ impl Arbitrary for std::time::Duration {
}
}

impl Arbitrary for std::char::EscapeUnicode {
fn any() -> Self {
// Generate any state reachable by consuming a freshly constructed
// EscapeUnicode iterator from the front.
let mut escape = char::any().escape_unicode();
let len = escape.len();

let front = usize::from(u8::any());
crate::assume(front <= len);

if front >= 1 {
let _ = escape.next();
}
if front >= 2 {
let _ = escape.next();
}
if front >= 3 {
let _ = escape.next();
}
if front >= 4 {
let _ = escape.next();
}
if front >= 5 {
let _ = escape.next();
}
if front >= 6 {
let _ = escape.next();
}
if front >= 7 {
let _ = escape.next();
}
if front >= 8 {
let _ = escape.next();
}
if front >= 9 {
let _ = escape.next();
}
if front >= 10 {
let _ = escape.next();
}

escape
}
}

/// Generate a slice of *unbounded* nondeterministic length: a fresh allocation of
/// nondeterministic size whose contents are nondeterministic, with element validity
/// established by `slice_validity_assume` (a compiler hook that emits a quantified
Expand Down
26 changes: 26 additions & 0 deletions tests/kani/char_escape_unicode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

//! Ensure that `kani::any` can generate valid `std::char::EscapeUnicode` states.

use std::char::EscapeUnicode;

#[kani::proof]
fn check_arbitrary_escape_unicode() {
let escape: EscapeUnicode = kani::any();
let count = escape.count();

assert!(count <= 10);

kani::cover!(count == 0);
kani::cover!(count == 1);
kani::cover!(count == 2);
kani::cover!(count == 3);
kani::cover!(count == 4);
kani::cover!(count == 5);
kani::cover!(count == 6);
kani::cover!(count == 7);
kani::cover!(count == 8);
kani::cover!(count == 9);
kani::cover!(count == 10);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright Kani Contributors
# SPDX-License-Identifier: Apache-2.0 OR MIT

[package]
name = "autoharness_char_escape_unicode"
version = "0.1.0"
edition = "2024"

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(kani)'] }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright Kani Contributors
# SPDX-License-Identifier: Apache-2.0 OR MIT

script: escape_unicode.sh
expected: escape_unicode.expected
exit_code: 0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
| autoharness_char_escape_unicode | consume_escape_unicode | #[kani::proof] | Success |
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash

# Copyright Kani Contributors
# SPDX-License-Identifier: Apache-2.0 OR MIT

set -euo pipefail

cargo kani autoharness -Z autoharness --output-format=regular 2>&1 \
| grep -E '^\| autoharness_char_escape_unicode \| consume_escape_unicode .*Success' \
| tr -s ' '
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT

#![allow(dead_code)]

pub fn consume_escape_unicode(value: std::char::EscapeUnicode) -> usize {
value.count()
}
Loading