Skip to content

Commit 8817d31

Browse files
celinvaltedinski
authored andcommitted
Add support to min_specialization for arbitrary / invariant (rust-lang#1029)
* Add support to mim_specialization for arbitrary / invariant We would like to enable users to provide custom implementations of Invariant and Arbitrary. Use feature `min_specialization` to allow that. Note that users will also need to enable that same feature in their code.
1 parent 2278bbb commit 8817d31

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

library/kani/src/arbitrary.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ impl<T> Arbitrary for T
1414
where
1515
T: Invariant,
1616
{
17-
fn any() -> Self {
17+
default fn any() -> Self {
1818
let value = unsafe { any_raw::<T>() };
1919
assume(value.is_valid());
2020
value

library/kani/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33
#![feature(rustc_attrs)] // Used for rustc_diagnostic_item.
4+
#![feature(min_specialization)] // Used for default implementation of Arbitrary.
45

56
pub mod arbitrary;
67
pub mod invariant;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
//
4+
// Check that users can implement Invariant and Arbitrary to the same struct.
5+
#![cfg_attr(kani, feature(min_specialization))]
6+
7+
extern crate kani;
8+
use kani::{Arbitrary, Invariant};
9+
10+
// Dummy wrappar that keeps track of the vector size.
11+
struct VecWrapper {
12+
has_data: bool,
13+
data: Vec<u8>,
14+
}
15+
16+
impl VecWrapper {
17+
fn new() -> Self {
18+
VecWrapper { has_data: false, data: Vec::new() }
19+
}
20+
21+
fn from(buf: &[u8]) -> Self {
22+
VecWrapper { has_data: true, data: Vec::from(buf) }
23+
}
24+
}
25+
26+
unsafe impl Invariant for VecWrapper {
27+
fn is_valid(&self) -> bool {
28+
self.has_data ^ self.data.is_empty()
29+
}
30+
}
31+
32+
impl Arbitrary for VecWrapper {
33+
fn any() -> Self {
34+
if kani::any() { VecWrapper::new() } else { VecWrapper::from(&[kani::any(), kani::any()]) }
35+
}
36+
}
37+
38+
#[kani::proof]
39+
fn check() {
40+
let wrap: VecWrapper = kani::any();
41+
assert!(wrap.is_valid());
42+
}

0 commit comments

Comments
 (0)