# Rust Contracts
Prusti Zulip: https://prusti.zulipchat.com/
## Contracts Supported by Prusti
### Attributes and Function-Like Contracts
Here `A` is an assertion (described below):
* `#[requires(A)]` – (function/method) precondition.
* `#[ensures(A)]` – (function/method) postcondition.
* `#[after_expiry(R => A)]` – pledge in a postcondition on reference `R`.
* `#[after_expiry_if(R => A, A)]` – guarded pledge in a postcondition on reference `R`.
* `body_invariant!(A)` – loop body invariant.
* `#[pure]` – marks the annotated function/method as pure.
* `#[trusted]` – marks the annotated function/method as trusted.
### Assertions
An assertion can be:
* A conjuction of assertions.
* An implication `A1 ==> A2` where `A1` and `A2` are assertions. (Note: due to [a bug](https://github.com/viperproject/prusti-dev/issues/127) in the Rust compiler, the implication with a space `== >` is also accepted by the parser).
* A quantifier `forall(|args| A, triggers)` where `args` are variables bound by the quantifier, `A` is an assertion, and `triggers` are the Rust expressions used to trigger the quantifier.
The parser treats `old` and `before_expiry` as regular function calls. The special semantics are given to them in the later stages of Prusti.
## Contracts Supported by `contracts`
Contracts generally have the shape `#[name(expr, expr, ... expr, "description")]`. The description has to be the last argument of the attribute and needs to be a string literal.
Only one expression is required but more can be used with `,` to create a conjunction.
All contracts have `debug_` and `test_` versions of the attributes (for example `debug_ensures` and `test_requires`) which are only checked in debug builds or when the `test` cfg is set.
### On functions (and methods)
Expressions are regular Rust expressions, "anything goes" (no side-effect checks since that's very tricky in a proc-macro crate).
Additionally expressions can contain `->` as a binary operator for implication. The `->` was chosen over `==>` due to `rustc` erasing spacing information when using `==>`.
- Preconditions
- `#[requires(x + 2 < self.len())]`
- Checked before the body of the function runs
- Postconditions
- `#[ensures(ret % 2 == 0)]`
- Checked after the body of the function ran
- The name `ret` is bound to the return value of the funtcion
- supports `old(expr)` in the contract expressions
- Generates a `let` binding with a generated name before the function body executes, the `old(..)` call gets replaced with the generated name
- Invariants
- `#[invariant(self.value <= 100)]`
- The same as a pre-condition *and* a post-condition with the same expression
- Because it needs to be a valid `#[pre]` condition the `old(expr)` function is not supported
### On `impl Type` blocks
- Invariants
- `#[invariant(self.value <= 100)]`
- Injects the `#[invariant]` attribute on all methods that take `&self` or `&mut self`
- Does not apply to `fn new() -> Self` or methods that move `self`
### On `trait`s and Trait `impl`s
To check contracts on traits at runtime a trait must be marked with the `#[contract_trait]`
To implement a trait with contracts also the `impl` block needs the `#[contract_trait]` attribute.
### Planned features
- `unchanged` attribute, `#[unchanged(expr)]` => `#[ensures(old(expr) == expr)]`
- ACSL like `behaviour` attributes to group together contracts for different behaviours of a function
- Loop invariants as function-like procedural macros
- "Ghost code" support for existential quantifiers
- universal quantifier `forall` inside contract expressions
## Syntax Differences between Prusti and `contracts`
* Different operators for implication (`==>` vs `->`).
* `contracts` attributes can have a string literal description as the last attribute argument
* `contracts` has different versions of attributes for debug and test environments
## Communalities between Prusti and `contracts`
* Both implemented completely by using Rust procedural macros.
* Assertions are structurally very similar: contain conjuctions and implications that connect Rust expressions.
* `old()` functions to use values from before the function body in post-conditions