Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Function Contracts: Closure Type Inference #3307

Merged
merged 8 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 4 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
4 changes: 4 additions & 0 deletions library/kani/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,7 @@ pub use kani_macros::*;
pub(crate) use kani_macros::unstable_feature as unstable;

pub mod contracts;

pub fn apply_closure<T, U: FnOnce(&T) -> bool>(f: U, x: &T) -> bool {
f(x)
}
2 changes: 1 addition & 1 deletion library/kani_macros/src/sysroot/contracts/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ pub fn build_ensures(data: &ExprClosure) -> (TokenStream2, Expr) {
.fold(quote!(), |collect, (ident, expr)| quote!(let #ident = #expr; #collect));

let result: Ident = Ident::new(INTERNAL_RESULT_IDENT, Span::call_site());
(remembers_stmts, Expr::Verbatim(quote!((#expr)(&#result))))
(remembers_stmts, Expr::Verbatim(quote!(kani::apply_closure(#expr, &#result))))
}

trait OldTrigger {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
assertion\
- Status: SUCCESS\
- Description: "|result| (*result == x) | (*result == y)"\
in function max

VERIFICATION:- SUCCESSFUL
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright Kani Contributors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// kani-flags: -Zfunction-contracts

#[kani::ensures(|result| (*result == x) | (*result == y))]
fn max(x: u32, y: u32) -> u32 {
if x > y { x } else { y }
}

#[kani::proof_for_contract(max)]
fn max_harness() {
let _ = Box::new(9_usize);
max(7, 6);
}