flux_rs/lib.rs
1#![no_std]
2#[cfg_attr(flux, flux::no_suggestions)]
3pub mod bitvec;
4
5pub use attrs::*;
6pub use flux_attrs as attrs;
7
8#[no_suggestions]
9#[sig(fn(bool[true]) )]
10pub fn assert(_: bool) {}
11
12#[no_suggestions]
13#[sig (fn() -> _ requires false)]
14pub fn unreachable() -> ! {
15 unreachable!("impossible case")
16}
17
18/// Macro for creating detached specifications.
19///
20/// # Example
21/// ```
22/// flux_rs::macros::detached_spec! {
23/// fn inc(n:i32) -> i32[n+1];
24/// fn watermelon(n:usize) -> usize[n+2];
25/// }
26/// ```
27#[macro_export]
28#[doc(hidden)]
29macro_rules! __private_detached_spec {
30 ($($e:tt)*) => {
31 #[$crate::specs {
32 $($e)*
33 }]
34 const _: () = ();
35 };
36}
37
38/// Macro for creating `invariant qualifier`s
39/// # Example
40/// ```
41/// invariant!(res: int, i: int, n: int ; res + i == n);
42/// ```
43#[macro_export]
44#[doc(hidden)]
45macro_rules! __private_invariant {
46 ($($param:ident : $ty:ty),* ; $expr:expr) => {
47 $crate::defs! {
48 invariant qualifier Auto($($param: $ty),*) { $expr }
49 }
50 $crate::assert($expr);
51 };
52}
53
54/// Macro for creating `invariant qualifier`s without an assertion.
55///
56/// Unlike [`invariant`](crate::macros::invariant), the body is never re-emitted as Rust, so it
57/// may use refinement-only syntax. Sorts are inferred; annotate the ones that can't be, using
58/// the same `params ; body` syntax as [`invariant`](crate::macros::invariant).
59///
60/// # Example
61/// ```
62/// flux_rs::macros::qualifier!(my_plus(res, i) == n);
63/// flux_rs::macros::qualifier!(res: int, i: int ; res + i == n);
64/// ```
65#[macro_export]
66#[doc(hidden)]
67macro_rules! __private_qualifier {
68 ($($param:ident : $ty:ty),+ ; $($body:tt)*) => {
69 $crate::defs! {
70 invariant qualifier Auto($($param: $ty),+) { $($body)* }
71 }
72 };
73 ($($body:tt)*) => {
74 $crate::defs! {
75 invariant qualifier Auto() { $($body)* }
76 }
77 };
78}
79
80pub mod macros {
81 /// Macro for creating detached specifications.
82 ///
83 /// # Example
84 /// ```
85 /// flux_rs::macros::detached_spec! {
86 /// fn inc(n:i32) -> i32[n+1];
87 /// fn watermelon(n:usize) -> usize[n+2];
88 /// }
89 /// ```
90 pub use crate::__private_detached_spec as detached_spec;
91 /// Macro for creating `invariant qualifier`s
92 /// # Example
93 /// ```
94 /// flux_rs::macros::invariant!(res: int, i: int, n: int ; res + i == n);
95 /// ```
96 pub use crate::__private_invariant as invariant;
97 /// Macro for creating a local `invariant qualifier` hint.
98 /// # Example
99 /// ```
100 /// flux_rs::macros::qualifier!(my_plus(res, i) == n);
101 /// flux_rs::macros::qualifier!(res: int, i: int ; res + i == n);
102 /// ```
103 pub use crate::__private_qualifier as qualifier;
104}