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