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}