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}