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