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