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}