This repository contains an experimental Rust frontend for the Stainless verifier.
Our frontend is implemented as an alternative driver for rustc, which means that we run the standard Rust compiler and intercept its high-level IR after type-checking.
For a given compilation unit we produce a set of Stainless ClassDef
s and FunDef
s, and serialize them to a file which can then be verified independently using a new Stainless interface called stainless-noxt
-- a "no-extraction" mode which merely deserializes the program representation from the previously generated file.
A Rust version of Stainless data structures and associated serialization code is located in the stainless_data
crate.
The actual code interfacing with rustc and performing program extraction is found in the stainless_extraction
and stainless_frontend
crates.
The following instructions assume that you have installed Rust using rustup.
-
Clone this repo in
/basedir/rust-stainless
. -
Make sure your
rustup
toolchain within that directory is set to the currently supported nightly version (viarustup override set $(cat rust-toolchain)
in/basedir/rust-stainless
). -
Make sure you have the
rustc-dev
andllvm-tools-preview
components installed (viarustup component add rustc-dev llvm-tools-preview
). -
Install
stainless_frontend
(viacargo install --path stainless_frontend/
). This will build therustc_to_stainless
driver, which is essentially a modified version ofrustc
, andcargo-stainless
, which provides a convenient way of invokingrustc_to_stainless
from within Cargo project folders. Installation ensures that both of these binaries end up on yourPATH
. -
Get a copy of the standalone version of
stainless-noxt
from the release of Stainless that has the tag stated in.stainless-version
. For example, this one with the archive for Linux or macOS. (This is based on forks of inox and stainless.) -
Extract it to
/basedir/stainless
. -
Make sure that your
STAINLESS_HOME
environment variable points to/basedir/stainless
.
Now you should be good to go.
Assuming you have followed the above installation instructions, using rustc_to_stainless
in basic Cargo projects is easy:
Navigate to a project folder (i.e., a folder containing a Cargo.toml
file), run cargo build
, and, consequently, cargo stainless
.
This will invoke rustc_to_stainless
for the last build target in your Cargo project with essentially the same configuration as cargo build
would.
The frontend will produce some debug output, and, if extraction is successful, send the program to stainless for verification.
Similarly to other cargo commands, you can also use cargo stainless --example foo
to instead extract a specific example.
Note that the fragment of Rust currently supported is very limited. The test cases give you a good impression of what works and what doesn't yet.
You can also verify the extracted programs directly using Stainless and the stainless-noxt
subproject.
First, export the serialized stainless program using cargo stainless --export output.inoxser
.
To then run verification on that file, navigate to your checked-out Stainless repo, run sbt
in the root folder of the repo, and consequently switch to the appropriate subproject using project stainless-noxt
.
The actual verification can be started using run /the/path/to/output.inoxser
.
The rust-stainless
frontend transforms Rust programs to Stainless trees which
are fed to the Stainless backend. The definition of these trees is in found in
stainless_data
and is automatically generated from the
Stainless repository.
If Stainless gets new features or a fix, it is sometimes necessary to regenerate the AST in order to
stay compatible with the latest version of the Stainless backend. This is done from the rust-interop
branch
on Stainless.
- Checkout the
rust-interop
branch. - Rebase or change what is needed.
- Run
sbt
and thenrunMain stainless.utils.RustInteropGeneratorTool generated.rs
. - Move the newly
generated.rs
file tostainless_data/src/ast/generated.rs
. - Rebuild and test the frontend to see whether everything still works and hope for the best.
- Georg Schmid (@gsps)
- Romain Ruetschi (@romac)
- Yann Bolliger (@yannbolliger)
- Ivan Yurov (@youroff - semester project, Spring 2020)