epfl-lara / rust-stainless

An experimental Rust frontend for Stainless
Apache License 2.0
6 stars 2 forks source link

A Rust frontend for Stainless

This repository contains an experimental Rust frontend for the Stainless verifier.

Overview

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 ClassDefs and FunDefs, 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.

Installation

The following instructions assume that you have installed Rust using rustup.

Now you should be good to go.

Usage

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.

What to expect

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.

Development

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.

Generating the Stainless ADT

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.

  1. Checkout the rust-interop branch.
  2. Rebase or change what is needed.
  3. Run sbt and then runMain stainless.utils.RustInteropGeneratorTool generated.rs.
  4. Move the newly generated.rs file to stainless_data/src/ast/generated.rs.
  5. Rebuild and test the frontend to see whether everything still works and hope for the best.

Contributors