Skip to content

Commit 7a7f654

Browse files
committed
improve documentation for generics
1 parent f060d66 commit 7a7f654

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

docs/src/reference/experimental/autoharness.md

+36-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Many proof harnesses follow this predictable format—to verify a function `foo`
1010

1111
The `autoharness` subcommand leverages this observation to automatically generate harnesses and run Kani against them.
1212
Kani scans the crate for functions whose arguments all implement the `kani::Arbitrary` trait, generates harnesses for them, then runs them.
13-
These harnesses are internal to Kani--i.e., Kani does not make any changes to your source code.
13+
These harnesses are internal to Kanii.e., Kani does not make any changes to your source code.
1414

1515
## Usage
1616
Run either:
@@ -76,9 +76,44 @@ If you have ideas for improving the user experience of this feature,
7676
please add them to [this GitHub issue](https://github.com/model-checking/kani/issues/3832).
7777

7878
## Limitations
79+
### Arguments Implementing Arbitrary
7980
Kani will only generate an automatic harness for a function if it can determine that all of the function's arguments implement Arbitrary.
8081
It does not attempt to derive/implement Arbitrary for any types, even if those types could implement Arbitrary.
82+
For example, imagine a user defines `struct MyStruct { x: u8, y: u8}`, but does not derive or implement Arbitrary for `MyStruct`.
83+
Kani does not attempt to add such derivations itself, so it will not generate a harness for a function that takes `MyStruct` as input.
8184

85+
### Generic Functions
86+
The current implementation does not generate harnesses for generic functions.
87+
For example, given:
88+
```rust
89+
fn foo<T: Eq>(x: T, y: T) {
90+
if x == y {
91+
panic!("x and y are equal");
92+
}
93+
}
94+
```
95+
Kani would report that no functions were eligible for automatic harness generation.
96+
97+
If, however, some caller of `foo` is eligible for an automatic harness, then a monomorphized version of `foo` may still be reachable during verification.
98+
For instance, if we add `main`:
99+
```rust
100+
fn main() {
101+
let x: u8 = 2;
102+
let y: u8 = 2;
103+
foo(x, y);
104+
}
105+
```
106+
and run the autoharness subcommand, we get:
107+
```
108+
Autoharness: Checking function main against all possible inputs...
109+
110+
Failed Checks: x and y are equal
111+
File: "src/lib.rs", line 3, in foo::<u8>
112+
113+
VERIFICATION:- FAILED
114+
```
115+
116+
### Loop Contracts
82117
If a function contains a loop with a loop contract, Kani will detect the presence of a loop contract and verify that contract.
83118
If, however, the loop does not have a contract, then there is currently no way to specify an unwinding bound for the function, meaning that Kani may hang as it tries to unwind the loop.
84119
We recommend using the `--exclude-function` option to exclude any functions that have this issue (or `--harness-timeout` to bail after attempting verification for some amount of time).

kani-compiler/src/kani_middle/codegen_units.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,9 @@ fn is_eligible_for_automatic_harness(tcx: TyCtxt, instance: Instance, any_inst:
366366
return false;
367367
}
368368

369-
// Each non-generic argument of `instance`` must implement Arbitrary.
369+
// Each argument of `instance` must implement Arbitrary.
370+
// Note that this function operates on StableMIR `Instance`s, which are eagerly monomorphized,
371+
// so none of these arguments are generic.
370372
body.arg_locals().iter().all(|arg| {
371373
let kani_any_body =
372374
Instance::resolve(any_inst, &GenericArgs(vec![GenericArgKind::Type(arg.ty)]))

0 commit comments

Comments
 (0)