Skip to main content

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