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