Skip to content

Commit b818553

Browse files
authored
Add loop_invariant predicate (#137)
Add `loop_invariant` to the `safety` crate. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent c4a1f45 commit b818553

File tree

4 files changed

+30
-3
lines changed

4 files changed

+30
-3
lines changed

library/contracts/safety/src/kani.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use proc_macro::{TokenStream};
22
use quote::{quote, format_ident};
3-
use syn::{ItemFn, parse_macro_input};
3+
use syn::{ItemFn, parse_macro_input, Stmt};
44

55
pub(crate) fn requires(attr: TokenStream, item: TokenStream) -> TokenStream {
66
rewrite_attr(attr, item, "requires")
@@ -10,6 +10,20 @@ pub(crate) fn ensures(attr: TokenStream, item: TokenStream) -> TokenStream {
1010
rewrite_attr(attr, item, "ensures")
1111
}
1212

13+
pub(crate) fn loop_invariant(attr: TokenStream, stmt: TokenStream) -> TokenStream {
14+
rewrite_stmt_attr(attr, stmt, "loop_invariant")
15+
}
16+
17+
fn rewrite_stmt_attr(attr: TokenStream, stmt_stream: TokenStream, name: &str) -> TokenStream {
18+
let args = proc_macro2::TokenStream::from(attr);
19+
let stmt = parse_macro_input!(stmt_stream as Stmt);
20+
let attribute = format_ident!("{}", name);
21+
quote!(
22+
#[kani_core::#attribute(#args)]
23+
#stmt
24+
).into()
25+
}
26+
1327
fn rewrite_attr(attr: TokenStream, item: TokenStream, name: &str) -> TokenStream {
1428
let args = proc_macro2::TokenStream::from(attr);
1529
let fn_item = parse_macro_input!(item as ItemFn);

library/contracts/safety/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,9 @@ pub fn requires(attr: TokenStream, item: TokenStream) -> TokenStream {
2323
pub fn ensures(attr: TokenStream, item: TokenStream) -> TokenStream {
2424
tool::ensures(attr, item)
2525
}
26+
27+
#[proc_macro_error]
28+
#[proc_macro_attribute]
29+
pub fn loop_invariant(attr: TokenStream, stmt_stream: TokenStream) -> TokenStream {
30+
tool::loop_invariant(attr, stmt_stream)
31+
}

library/contracts/safety/src/runtime.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ pub(crate) fn requires(_attr: TokenStream, item: TokenStream) -> TokenStream {
77
item
88
}
99

10-
/// For now, runtime requires is a no-op.
10+
/// For now, runtime ensures is a no-op.
1111
///
1212
/// TODO: At runtime the `ensures` should become an assert as well.
1313
pub(crate) fn ensures(_attr: TokenStream, item: TokenStream) -> TokenStream {
1414
item
1515
}
16+
17+
/// For now, runtime loop_invariant is a no-op.
18+
///
19+
/// TODO: At runtime the `loop_invariant` should become an assert as well.
20+
pub(crate) fn loop_invariant(_attr: TokenStream, stmt_stream: TokenStream) -> TokenStream {
21+
stmt_stream
22+
}

tool_config/kani-version.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# This version should be updated whenever there is a change that makes this version of kani
2-
# incomaptible with the verify-std repo.
2+
# incompatible with the verify-std repo.
33

44
[kani]
55
commit = "5f8f513d297827cfdce4c48065e51973ba563068"

0 commit comments

Comments
 (0)