creusot_contracts/
lib.rs

1//! The "standard library" of Creusot.
2//!
3//! To start using Creusot, you should always import that crate. The recommended way is
4//! to have a glob import:
5//!
6//! ```
7//! use creusot_contracts::*;
8//! ```
9//!
10//! # Writing specifications
11//!
12//! To start writing specification, use the [`requires`] and [`ensures`] macros:
13//!
14//! ```
15//! use creusot_contracts::*;
16//!
17//! #[requires(x < i32::MAX)]
18//! #[ensures(result@ == x@ + 1)]
19//! fn add_one(x: i32) -> i32 {
20//!     x + 1
21//! }
22//! ```
23//!
24//! For a more detailed explanation, see the [guide](https://creusot-rs.github.io/creusot/guide).
25//!
26//! # Module organization
27//!
28//! 1. Core features of Creusot
29//!
30//!     - [`invariant`][mod@invariant]: Type invariants
31//!     - [`macros`]: `#[requires]`, `#[ensures]`, etc.
32//!     - [`resolve`][mod@resolve]: Resolve mutable borrows
33//!     - [`snapshot`][mod@snapshot]: Snapshots
34//!
35//! 2. [`logic`][mod@logic]: Logical structures used in specifications
36//!
37//! 3. [`ghost`][mod@ghost]: Ghost code
38//!
39//! 4. [`std`][mod@std]: Specifications for the `std` crate
40//!
41//! 5. [`cell`][mod@cell]: Interior mutability
42//!
43//! 6. [`prelude`][mod@prelude]: What you get from `use creusot_contracts::*;`
44#![cfg_attr(
45    feature = "nightly",
46    allow(incomplete_features, internal_features),
47    feature(
48        const_destruct,
49        fn_traits,
50        print_internals,
51        fmt_internals,
52        fmt_helpers_for_derive,
53        step_trait,
54        try_trait_v2,
55        allocator_api,
56        unboxed_closures,
57        tuple_trait,
58        panic_internals,
59        libstd_sys_internals,
60        rt,
61        never_type,
62        ptr_metadata,
63        hint_must_use,
64    )
65)]
66
67extern crate creusot_contracts_proc as base_macros;
68extern crate self as creusot_contracts;
69
70/// Specification are written using these macros
71///
72/// All of those are re-exported at the top of the crate.
73pub mod macros {
74    /// A pre-condition of a function or trait item
75    ///
76    /// The inside of a `requires` may look like Rust code, but it is in fact
77    /// [pearlite](https://creusot-rs.github.io/creusot/guide/pearlite).
78    ///
79    /// # Example
80    ///
81    /// ```
82    /// # use creusot_contracts::*;
83    /// #[requires(x@ == 1)]
84    /// fn foo(x: i32) {}
85    /// ```
86    pub use base_macros::requires;
87
88    /// A post-condition of a function or trait item
89    ///
90    /// The inside of a `ensures` may look like Rust code, but it is in fact
91    /// [pearlite](https://creusot-rs.github.io/creusot/guide/pearlite).
92    ///
93    /// # Example
94    ///
95    /// ```
96    /// # use creusot_contracts::*;
97    /// #[ensures(result@ == 1)]
98    /// fn foo() -> i32 { 1 }
99    /// ```
100    pub use base_macros::ensures;
101
102    /// Create a new [`Snapshot`](crate::Snapshot) object.
103    ///
104    /// The inside of `snapshot` may look like Rust code, but it is in fact
105    /// [pearlite](https://creusot-rs.github.io/creusot/guide/pearlite).
106    ///
107    /// # Example
108    ///
109    /// ```
110    /// # use creusot_contracts::*;
111    /// let mut x = 1;
112    /// let s = snapshot!(x);
113    /// x = 2;
114    /// proof_assert!(*s == 1i32);
115    /// ```
116    ///
117    /// # `snapshot!` and ownership
118    ///
119    /// Snapshots are used to talk about the logical value of an object, and as such
120    /// they carry no ownership. This means that code like this is perfectly fine:
121    ///
122    /// ```
123    /// # use creusot_contracts::{*, vec};
124    /// let v: Vec<i32> = vec![1, 2];
125    /// let s = snapshot!(v);
126    /// assert!(v[0] == 1); // ok, `s` does not have ownership of `v`
127    /// drop(v);
128    /// proof_assert!(s[0] == 1i32); // also ok!
129    /// ```
130    pub use base_macros::snapshot;
131
132    /// Opens a 'ghost block'.
133    ///
134    /// Ghost blocks are used to execute ghost code: code that will be erased in the
135    /// normal execution of the program, but could influence the proof.
136    ///
137    /// Note that ghost blocks are subject to some constraints, that ensure the behavior
138    /// of the code stays the same with and without ghost blocks:
139    /// - They may not contain code that crashes or runs indefinitely. In other words,
140    ///   they can only call [`check(ghost)`][check#checkghost] functions.
141    /// - All variables that are read in the ghost block must either be [`Copy`], or a
142    ///   [`Ghost`].
143    /// - All variables that are modified in the ghost block must be [`Ghost`]s.
144    /// - The variable returned by the ghost block will automatically be wrapped in a
145    ///   [`Ghost`].
146    ///
147    /// # Example
148    ///
149    /// ```
150    /// # use creusot_contracts::*;
151    /// let x = 1;
152    /// let mut g = ghost!(Seq::new()); // g is a zero-sized variable at runtime
153    /// ghost! {
154    ///     g.push_back_ghost(x);
155    /// };
156    /// ```
157    ///
158    /// [`Ghost`]: crate::ghost::Ghost
159    pub use base_macros::ghost;
160
161    pub use base_macros::ghost_let;
162
163    /// Specify that the function can be called in additionnal contexts.
164    ///
165    /// # Syntax
166    ///
167    /// Checking modes are specified as arguments:
168    ///
169    /// ```
170    /// # use creusot_contracts::*;
171    /// #[check(terminates)]
172    /// fn foo() { /* */ }
173    ///
174    /// #[check(ghost)]
175    /// fn bar() { /* */ }
176    ///
177    /// // cannot be called in neither ghost nor terminates contexts
178    /// fn baz() { /* */ }
179    /// ```
180    ///
181    /// # `#[check(terminates)]`
182    ///
183    /// The function is guaranteed to terminate.
184    ///
185    /// At this moment, this means that:
186    /// - the function cannot be recursive
187    /// - the function cannot contain loops
188    /// - the function can only call other `terminates` or `ghost` functions.
189    ///
190    /// The first two limitations may be lifted at some point.
191    ///
192    /// # `#[check(ghost)]`
193    ///
194    /// The function can be called from ghost code. In particular, this means
195    /// that the fuction will not panic.
196    ///
197    /// # No panics ?
198    ///
199    /// "But I though Creusot was supposed to check the absence of panics ?"
200    ///
201    /// That's true, but with a caveat: some functions of the standard library
202    /// are allowed to panic in specific cases. The main example is `Vec::push`:
203    /// we want its specification to be
204    /// ```ignore
205    /// #[ensures((^self)@ == self@.push(v))]
206    /// fn push(&mut self, v: T) { /* ... */ }
207    /// ```
208    ///
209    /// But the length of a vector [cannot overflow `isize::MAX`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.push).
210    /// This is a very annoying condition to check, so we don't. In exchange,
211    /// this means `Vec::push` might panic in some cases, even though your
212    /// code passed Creusot's verification.
213    ///
214    /// # Non-ghost std function
215    ///
216    /// Here are some examples of functions in `std` that are not marked as
217    /// `terminates` but not `ghost` (this list is not exhaustive):
218    /// - `Vec::push`, `Vec::insert`, `Vec::reserve`, `Vec::with_capacity`
219    /// - `str::to_string`
220    /// - `<&[T]>::into_vec`
221    /// - `Deque::push_front`, `Deque::push_back`, `Deque::with_capacity`
222    pub use base_macros::check;
223
224    /// A loop invariant
225    ///
226    /// The inside of a `invariant` may look like Rust code, but it is in fact
227    /// [pearlite](https://creusot-rs.github.io/creusot/guide/pearlite).
228    ///
229    /// # Produced
230    ///
231    /// If the loop is a `for` loop, you have access to a special variable `produced`, that
232    /// holds a [sequence](crate::Seq) of all the (logical representations of) items the
233    /// iterator yielded so far.
234    ///
235    /// # Example
236    ///
237    /// ```ignore
238    /// # use creusot_contracts::*;
239    /// let mut v = Vec::new();
240    /// #[invariant(v@.len() == produced.len())]
241    /// #[invariant(forall<j> 0 <= j && j < produced.len() ==> v@[j]@ == j)]
242    /// for i in 0..10 {
243    ///     v.push(i);
244    /// }
245    /// ```
246    pub use base_macros::invariant;
247
248    /// Declare a function as being a logical function
249    ///
250    /// This declaration must be pure and total. It cannot be called from Rust programs,
251    /// but in exchange it can use logical operations and syntax with the help of the
252    /// [`pearlite!`] macro.
253    ///
254    /// # `open`
255    ///
256    /// Allows the body of a logical definition to be made visible to provers
257    ///
258    /// By default, bodies are *opaque*: they are only visible to definitions in the same
259    /// module (like `pub(self)` for visibility).
260    /// An optional visibility modifier can be provided to restrict the context in which
261    /// the body is opened.
262    ///
263    /// A body can only be visible in contexts where all the symbols used in the body are also visible.
264    /// This means you cannot open a body which refers to a `pub(crate)` symbol.
265    ///
266    /// # Example
267    ///
268    /// ```
269    /// mod inner {
270    ///     use creusot_contracts::*;
271    ///     #[logic]
272    ///     #[ensures(result == x + 1)]
273    ///     pub(super) fn foo(x: Int) -> Int {
274    ///         // ...
275    /// # x + 1
276    ///     }
277    ///
278    ///     #[logic(open)]
279    ///     pub(super) fn bar(x: Int) -> Int {
280    ///         x + 1
281    ///     }
282    /// }
283    ///
284    /// // The body of `foo` is not visible here, only the `ensures`.
285    /// // But the whole body of `bar` is visible
286    /// ```
287    ///
288    /// # `prophetic`
289    ///
290    /// If you wish to use the `^` operator on mutable borrows to get the final value, you need to
291    /// specify that the function is _prophetic_, like so:
292    /// ```
293    /// # use creusot_contracts::*;
294    /// #[logic(prophetic)]
295    /// fn uses_prophecies(x: &mut Int) -> Int {
296    ///     pearlite! { if ^x == 0 { 0 } else { 1 } }
297    /// }
298    /// ```
299    /// Such a logic function cannot be used in [`snapshot!`] anymore, and cannot be
300    /// called from a regular [`logic`] function.
301    ///
302    /// # law
303    ///
304    /// Declares a trait item as being a law which is autoloaded as soon another
305    /// trait item is used in a function.
306    ///
307    /// ```ignore
308    /// trait CommutativeOp {
309    ///     fn op(self, other: Self) -> Int;
310    ///
311    ///     #[logic(law)]
312    ///     #[ensures(forall<x: Self, y: Self> x.op(y) == y.op(x))]
313    ///     fn commutative();
314    /// }
315    /// ```
316    pub use base_macros::logic;
317
318    /// Inserts a *logical* assertion into the code
319    ///
320    /// This assertion will not be checked at runtime but only during proofs. However,
321    /// it can use [pearlite](https://creusot-rs.github.io/creusot/guide/pearlite) syntax.
322    ///
323    /// # Example
324    ///
325    /// ```
326    /// # use creusot_contracts::{*, vec};
327    /// let x = 1;
328    /// let v = vec![x, 2];
329    /// let s = snapshot!(v);
330    /// proof_assert!(s[0] == 1i32);
331    /// ```
332    pub use base_macros::proof_assert;
333
334    /// Makes a logical definition or a type declaration opaque, meaning that users of this declaration will not see
335    /// its definition.
336    ///
337    /// # Example
338    ///
339    /// ```
340    /// # use creusot_contracts::*;
341    /// #[opaque]
342    /// struct Opaque(()); // This will is an abstract type
343    ///
344    /// #[logic]
345    /// #[opaque] // Synonym: #[logic(opaque)]
346    /// fn foo() -> i32 { // This is an uninterpreted logic function
347    ///     dead
348    /// }
349    /// ```
350    pub use base_macros::opaque;
351
352    /// Instructs Creusot to not emit any VC for a declaration, assuming any contract the declaration has is
353    /// valid.
354    ///
355    /// # Example
356    ///
357    /// ```
358    /// # use creusot_contracts::*;
359    /// #[trusted] // this is too hard to prove :(
360    /// #[ensures(result@ == 1)]
361    /// fn foo() -> i32 {
362    ///     // complicated code...
363    /// # 1
364    /// }
365    /// ```
366    ///
367    /// These declarations are part of the trusted computing base (TCB). You should strive to use
368    /// this as little as possible.
369    pub use base_macros::trusted;
370
371    /// Declares a variant for a function or a loop.
372    ///
373    /// This is primarily used in combination with recursive logical functions.
374    ///
375    /// The variant must be an expression whose type implements
376    /// [`WellFounded`](crate::logic::WellFounded).
377    ///
378    /// # Example
379    ///
380    /// - Recursive logical function:
381    /// ```
382    /// # use creusot_contracts::*;
383    /// #[logic]
384    /// #[variant(x)]
385    /// #[requires(x >= 0)]
386    /// fn recursive_add(x: Int, y: Int) -> Int {
387    ///     if x == 0 {
388    ///         y
389    ///     } else {
390    ///         recursive_add(x - 1, y + 1)
391    ///     }
392    /// }
393    /// ```
394    /// - Loop variant:
395    /// ```
396    /// # use creusot_contracts::*;
397    /// #[check(terminates)]
398    /// #[ensures(result == x)]
399    /// fn inneficient_identity(mut x: i32) -> i32 {
400    ///     let mut res = 0;
401    ///     let total = snapshot!(x);
402    ///     // Attribute on loop are experimental in Rust, just pretend the next 2 lines are uncommented :)
403    ///     // #[variant(x)]
404    ///     // #[invariant(x@ + res@ == total@)]
405    ///     while x > 0 {
406    ///         x -= 1;
407    ///         res += 1;
408    ///     }
409    ///     res
410    /// }
411    /// ```
412    pub use base_macros::variant;
413
414    /// Enables [pearlite](https://creusot-rs.github.io/creusot/guide/pearlite) syntax, granting access to Pearlite specific operators and syntax
415    ///
416    /// This is meant to be used in [`logic`] functions.
417    ///
418    /// # Example
419    ///
420    /// ```
421    /// # use creusot_contracts::*;
422    /// #[logic]
423    /// fn all_ones(s: Seq<Int>) -> bool {
424    ///     // Allow access to `forall` and `==>` among other things
425    ///     pearlite! {
426    ///         forall<i> 0 <= i && i < s.len() ==> s[i] == 1
427    ///     }
428    /// }
429    /// ```
430    pub use base_macros::pearlite;
431
432    /// Allows specifications to be attached to functions coming from external crates
433    ///
434    /// TODO: Document syntax
435    pub use base_macros::extern_spec;
436
437    /// Allows specifying both a pre- and post-condition in a single statement.
438    ///
439    /// Expects an expression in either the form of a method or function call
440    /// Arguments to the call can be prefixed with `mut` to indicate that they are mutable borrows.
441    ///
442    /// Generates a `requires` and `ensures` clause in the shape of the input expression, with
443    /// `mut` replaced by `*` in the `requires` and `^` in the ensures.
444    pub use base_macros::maintains;
445
446    /// This attribute can be used on a function or closure to instruct Creusot not to ensure as a postcondition that the
447    /// return value of the function satisfies its [type invariant](crate::Invariant).
448    pub use base_macros::open_inv_result;
449
450    /// This attribute indicates that the function need to be proved in "bitwise" mode, which means that Creusot will use
451    /// the bitvector theory of SMT solvers.
452    pub use base_macros::bitwise_proof;
453
454    /// This attribute indicates that a logic function or a type should be translated to a specific type in Why3.
455    pub use base_macros::builtin;
456
457    /// Check that the annotated function erases to another function.
458    ///
459    /// See the [guide: Erasure check](https://creusot-rs.github.io/creusot/guide/erasure.html).
460    ///
461    /// # Usage
462    ///
463    /// ```
464    /// # use creusot_contracts::*;
465    /// #[erasure(f)]
466    /// fn g(x: usize, i: Ghost<Int>) { /* ... */ }
467    ///
468    /// #[erasure(private crate_name::full::path::to::f2)]
469    /// fn g2(y: bool) { /* ... */ }
470    /// ```
471    ///
472    /// # Inside `extern_spec!`
473    ///
474    /// The shorter `#[erasure]` (without argument) can be used in `extern_spec!` to check
475    /// that the annotated function body matches the original one.
476    ///
477    /// ```
478    /// # use creusot_contracts::*;
479    /// extern_spec! {
480    ///   #[erasure]
481    ///   fn some_external_function() { /* ... */ }
482    /// }
483    /// ```
484    pub use base_macros::erasure;
485
486    pub(crate) use base_macros::intrinsic;
487}
488
489#[doc(hidden)]
490#[cfg(creusot)]
491#[path = "stubs.rs"]
492pub mod __stubs;
493
494pub mod cell;
495pub mod ghost;
496pub mod invariant;
497pub mod logic;
498pub mod model;
499pub mod peano;
500pub mod resolve;
501pub mod snapshot;
502#[cfg_attr(not(creusot), allow(unused))]
503pub mod std;
504
505// We add some common things at the root of the creusot-contracts library
506mod base_prelude {
507    pub use crate::{
508        ghost::Ghost,
509        invariant::Invariant,
510        logic::{Int, OrdLogic, Seq, ops::IndexLogic as _},
511        model::{DeepModel, View},
512        resolve::Resolve,
513        snapshot::Snapshot,
514        std::{
515            // Shadow std::prelude by our version.
516            // For Clone, Default and PartialEq, this is important for the derive macro.
517            // If the user write the glob pattern "use creusot_contracts::*", then
518            // rustc will either shadow the old identifier or complain about the
519            // ambiguity (ex: for the derive macros Clone and PartialEq, a glob
520            // pattern is not enough to force rustc to use our version, but at least
521            // we get an error message).
522            clone::Clone,
523            cmp::PartialEq,
524            default::Default,
525            iter::{FromIterator, Iterator},
526        },
527    };
528
529    // Export extension traits anonymously
530    pub use crate::std::{
531        char::CharExt as _,
532        iter::{SkipExt as _, TakeExt as _},
533        ops::{FnExt as _, FnMutExt as _, FnOnceExt as _, RangeInclusiveExt as _},
534        option::OptionExt as _,
535        ptr::PointerExt as _,
536        slice::SliceExt as _,
537    };
538
539    #[cfg(creusot)]
540    pub use crate::{invariant::inv, resolve::resolve};
541}
542/// Re-exports available under the `creusot_contracts` namespace
543pub mod prelude {
544    pub use crate::{base_prelude::*, macros::*};
545}
546
547pub use prelude::*;
548
549/// Creusot-friendly replacement of `vec!`
550///
551/// The std vec macro uses special magic to construct the array argument
552/// to `Box::new` directly on the heap. Because the generated MIR is hard
553/// to translate, we provide a custom `vec!` macro which does not do this.
554#[macro_export]
555macro_rules! vec {
556    () => (
557        ::std::vec::Vec::new()
558    );
559    ($elem:expr; $n:expr) => (
560        ::std::vec::from_elem($elem, $n)
561    );
562    ($($x:expr),*) => (
563        <[_]>::into_vec(::std::boxed::Box::new([$($x),*]))
564    );
565    ($($x:expr,)*) => (vec![$($x),*])
566}