"]
5 | categories = ["development-tools::procedural-macro-helpers"]
6 | description = "Syntax tree describing Syn's syntax tree"
7 | documentation = "https://docs.rs/syn-codegen"
8 | edition = "2021"
9 | keywords = ["syn"]
10 | license = "MIT OR Apache-2.0"
11 | repository = "https://github.com/dtolnay/syn"
12 |
13 | [features]
14 | default = ["serde"]
15 | serde = ["dep:serde", "dep:serde_derive", "indexmap/serde", "semver/serde"]
16 |
17 | [dependencies]
18 | indexmap = "2"
19 | semver = "1"
20 | serde = { version = "1.0.88", optional = true }
21 | serde_derive = { version = "1.0.88", optional = true }
22 |
23 | [dev-dependencies]
24 | serde_json = "1"
25 |
26 | [lib]
27 | doc-scrape-examples = false
28 |
29 | [package.metadata.docs.rs]
30 | targets = ["x86_64-unknown-linux-gnu"]
31 | rustdoc-args = ["--generate-link-to-definition"]
32 |
33 | [workspace]
34 |
--------------------------------------------------------------------------------
/dependencies/syn/rustfmt.toml:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/dependencies/syn/rustfmt.toml
--------------------------------------------------------------------------------
/dependencies/syn/src/print.rs:
--------------------------------------------------------------------------------
1 | use proc_macro2::TokenStream;
2 | use quote::ToTokens;
3 |
4 | pub(crate) struct TokensOrDefault<'a, T: 'a>(pub &'a Option);
5 |
6 | impl<'a, T> ToTokens for TokensOrDefault<'a, T>
7 | where
8 | T: ToTokens + Default,
9 | {
10 | fn to_tokens(&self, tokens: &mut TokenStream) {
11 | match self.0 {
12 | Some(t) => t.to_tokens(tokens),
13 | None => T::default().to_tokens(tokens),
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/dependencies/syn/src/sealed.rs:
--------------------------------------------------------------------------------
1 | #[cfg(feature = "parsing")]
2 | pub(crate) mod lookahead {
3 | pub trait Sealed: Copy {}
4 | }
5 |
--------------------------------------------------------------------------------
/dependencies/syn/src/verbatim.rs:
--------------------------------------------------------------------------------
1 | use crate::parse::ParseStream;
2 | use proc_macro2::{Delimiter, TokenStream};
3 | use std::cmp::Ordering;
4 | use std::iter;
5 |
6 | pub(crate) fn between<'a>(begin: ParseStream<'a>, end: ParseStream<'a>) -> TokenStream {
7 | let end = end.cursor();
8 | let mut cursor = begin.cursor();
9 | assert!(crate::buffer::same_buffer(end, cursor));
10 |
11 | let mut tokens = TokenStream::new();
12 | while cursor != end {
13 | let (tt, next) = cursor.token_tree().unwrap();
14 |
15 | if crate::buffer::cmp_assuming_same_buffer(end, next) == Ordering::Less {
16 | // A syntax node can cross the boundary of a None-delimited group
17 | // due to such groups being transparent to the parser in most cases.
18 | // Any time this occurs the group is known to be semantically
19 | // irrelevant. https://github.com/dtolnay/syn/issues/1235
20 | if let Some((inside, _span, after)) = cursor.group(Delimiter::None) {
21 | assert!(next == after);
22 | cursor = inside;
23 | continue;
24 | } else {
25 | panic!("verbatim end must not be inside a delimited group");
26 | }
27 | }
28 |
29 | tokens.extend(iter::once(tt));
30 | cursor = next;
31 | }
32 | tokens
33 | }
34 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/common/mod.rs:
--------------------------------------------------------------------------------
1 | #![allow(dead_code)]
2 | #![allow(clippy::module_name_repetitions, clippy::shadow_unrelated)]
3 |
4 | pub mod eq;
5 | pub mod parse;
6 | pub mod visit;
7 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/common/parse.rs:
--------------------------------------------------------------------------------
1 | extern crate rustc_ast;
2 | extern crate rustc_driver;
3 | extern crate rustc_expand;
4 | extern crate rustc_parse as parse;
5 | extern crate rustc_session;
6 | extern crate rustc_span;
7 |
8 | use rustc_ast::ast;
9 | use rustc_ast::ptr::P;
10 | use rustc_session::parse::ParseSess;
11 | use rustc_span::FileName;
12 | use std::panic;
13 |
14 | pub fn librustc_expr(input: &str) -> Option> {
15 | match panic::catch_unwind(|| {
16 | let locale_resources = rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec();
17 | let sess = ParseSess::new(locale_resources);
18 | let name = FileName::Custom("test_precedence".to_string());
19 | let mut parser = parse::new_parser_from_source_str(&sess, name, input.to_string()).unwrap();
20 | let presult = parser.parse_expr();
21 | match presult {
22 | Ok(expr) => Some(expr),
23 | Err(diagnostic) => {
24 | diagnostic.emit();
25 | None
26 | }
27 | }
28 | }) {
29 | Ok(Some(e)) => Some(e),
30 | Ok(None) => None,
31 | Err(_) => {
32 | errorf!("librustc panicked\n");
33 | None
34 | }
35 | }
36 | }
37 |
38 | pub fn syn_expr(input: &str) -> Option {
39 | match syn::parse_str(input) {
40 | Ok(e) => Some(e),
41 | Err(msg) => {
42 | errorf!("syn failed to parse\n{:?}\n", msg);
43 | None
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/features/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "syn-test-suite"
3 | version = "0.0.0"
4 | authors = ["David Tolnay "]
5 | edition = "2021"
6 | publish = false
7 |
8 | [lib]
9 | path = "lib.rs"
10 |
11 | [dependencies]
12 | build-alert = "0.1"
13 |
14 | [features]
15 | all-features = []
16 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/features/lib.rs:
--------------------------------------------------------------------------------
1 | #[cfg(debug_assertions)]
2 | build_alert::yellow! {"
3 | NOTE: use --release
4 | Syn's test suite has some tests that run on every source file
5 | and test case in the rust-lang/rust repo, which can be pretty
6 | slow in debug mode. Consider running cargo test with `--release`
7 | to speed things up.
8 | "}
9 |
10 | #[cfg(not(feature = "all-features"))]
11 | build_alert::red! {"
12 | ERROR: use --all-features
13 | Syn's test suite normally only works with all-features enabled.
14 | Run again with `--all-features`, or run with `--features test`
15 | to bypass this check.
16 | "}
17 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/regression.rs:
--------------------------------------------------------------------------------
1 | #![allow(clippy::let_underscore_untyped, clippy::uninlined_format_args)]
2 |
3 | mod regression {
4 | automod::dir!("tests/regression");
5 | }
6 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/regression/issue1108.rs:
--------------------------------------------------------------------------------
1 | #[test]
2 | fn issue1108() {
3 | let data = "impl>::x for";
4 | let _ = syn::parse_file(data);
5 | }
6 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/regression/issue1235.rs:
--------------------------------------------------------------------------------
1 | use proc_macro2::{Delimiter, Group};
2 | use quote::quote;
3 |
4 | #[test]
5 | fn main() {
6 | // Okay. Rustc allows top-level `static` with no value syntactically, but
7 | // not semantically. Syn parses as Item::Verbatim.
8 | let tokens = quote! {
9 | pub static FOO: usize;
10 | pub static BAR: usize;
11 | };
12 | let file = syn::parse2::(tokens).unwrap();
13 | println!("{:#?}", file);
14 |
15 | // Okay.
16 | let inner = Group::new(
17 | Delimiter::None,
18 | quote!(static FOO: usize = 0; pub static BAR: usize = 0),
19 | );
20 | let tokens = quote!(pub #inner;);
21 | let file = syn::parse2::(tokens).unwrap();
22 | println!("{:#?}", file);
23 |
24 | // Formerly parser crash.
25 | let inner = Group::new(
26 | Delimiter::None,
27 | quote!(static FOO: usize; pub static BAR: usize),
28 | );
29 | let tokens = quote!(pub #inner;);
30 | let file = syn::parse2::(tokens).unwrap();
31 | println!("{:#?}", file);
32 | }
33 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/repo/progress.rs:
--------------------------------------------------------------------------------
1 | use std::io::{Read, Result};
2 | use std::time::{Duration, Instant};
3 |
4 | pub struct Progress {
5 | bytes: usize,
6 | tick: Instant,
7 | stream: R,
8 | }
9 |
10 | impl Progress {
11 | pub fn new(stream: R) -> Self {
12 | Progress {
13 | bytes: 0,
14 | tick: Instant::now() + Duration::from_millis(2000),
15 | stream,
16 | }
17 | }
18 | }
19 |
20 | impl Read for Progress {
21 | fn read(&mut self, buf: &mut [u8]) -> Result {
22 | let num = self.stream.read(buf)?;
23 | self.bytes += num;
24 | let now = Instant::now();
25 | if now > self.tick {
26 | self.tick = now + Duration::from_millis(500);
27 | errorf!("downloading... {} bytes\n", self.bytes);
28 | }
29 | Ok(num)
30 | }
31 | }
32 |
33 | impl Drop for Progress {
34 | fn drop(&mut self) {
35 | errorf!("done ({} bytes)\n", self.bytes);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/test_asyncness.rs:
--------------------------------------------------------------------------------
1 | #![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)]
2 |
3 | #[macro_use]
4 | mod macros;
5 |
6 | use syn::{Expr, Item};
7 |
8 | #[test]
9 | fn test_async_fn() {
10 | let input = "async fn process() {}";
11 |
12 | snapshot!(input as Item, @r#"
13 | Item::Fn {
14 | vis: Visibility::Inherited,
15 | sig: Signature {
16 | asyncness: Some,
17 | ident: "process",
18 | generics: Generics,
19 | output: ReturnType::Default,
20 | },
21 | block: Block {
22 | stmts: [],
23 | },
24 | }
25 | "#);
26 | }
27 |
28 | #[test]
29 | fn test_async_closure() {
30 | let input = "async || {}";
31 |
32 | snapshot!(input as Expr, @r#"
33 | Expr::Closure {
34 | asyncness: Some,
35 | output: ReturnType::Default,
36 | body: Expr::Block {
37 | block: Block {
38 | stmts: [],
39 | },
40 | },
41 | }
42 | "#);
43 | }
44 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/test_token_trees.rs:
--------------------------------------------------------------------------------
1 | #![allow(clippy::needless_lifetimes, clippy::uninlined_format_args)]
2 |
3 | #[macro_use]
4 | mod macros;
5 |
6 | use proc_macro2::TokenStream;
7 | use quote::quote;
8 | use syn::Lit;
9 |
10 | #[test]
11 | fn test_struct() {
12 | let input = "
13 | #[derive(Debug, Clone)]
14 | pub struct Item {
15 | pub ident: Ident,
16 | pub attrs: Vec,
17 | }
18 | ";
19 |
20 | snapshot!(input as TokenStream, @r##"
21 | TokenStream(
22 | `# [derive (Debug , Clone)] pub struct Item { pub ident : Ident , pub attrs : Vec < Attribute >, }`,
23 | )
24 | "##);
25 | }
26 |
27 | #[test]
28 | fn test_literal_mangling() {
29 | let code = "0_4";
30 | let parsed: Lit = syn::parse_str(code).unwrap();
31 | assert_eq!(code, quote!(#parsed).to_string());
32 | }
33 |
--------------------------------------------------------------------------------
/dependencies/syn/tests/zzz_stable.rs:
--------------------------------------------------------------------------------
1 | #![cfg(syn_disable_nightly_tests)]
2 |
3 | use std::io::{self, Write};
4 | use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};
5 |
6 | const MSG: &str = "\
7 | ‖
8 | ‖ WARNING:
9 | ‖ This is not a nightly compiler so not all tests were able to
10 | ‖ run. Syn includes tests that compare Syn's parser against the
11 | ‖ compiler's parser, which requires access to unstable librustc
12 | ‖ data structures and a nightly compiler.
13 | ‖
14 | ";
15 |
16 | #[test]
17 | fn notice() -> io::Result<()> {
18 | let header = "WARNING";
19 | let index_of_header = MSG.find(header).unwrap();
20 | let before = &MSG[..index_of_header];
21 | let after = &MSG[index_of_header + header.len()..];
22 |
23 | let mut stderr = StandardStream::stderr(ColorChoice::Auto);
24 | stderr.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
25 | write!(&mut stderr, "{}", before)?;
26 | stderr.set_color(ColorSpec::new().set_bold(true).set_fg(Some(Color::Yellow)))?;
27 | write!(&mut stderr, "{}", header)?;
28 | stderr.set_color(ColorSpec::new().set_fg(Some(Color::Yellow)))?;
29 | write!(&mut stderr, "{}", after)?;
30 | stderr.reset()?;
31 |
32 | Ok(())
33 | }
34 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | This directory contains various example files of programs to verify.
2 |
3 | There is a test in `rust_verify/tests/examples.rs` that attempts to run the verify on all .rs files in `example`, unless tagged as "ignore".
4 | The test will check the verification outcome based on the mode specified in the tag.
5 | The tag is specified by adding the following as the *first line*:
6 |
7 | ```
8 | // rust_verify/tests/example.rs [---] [optional comment]
9 | ```
10 |
11 | where `` is one of:
12 | * `expect-success` (default) expects the verification to succeed, reporting zero verification failures,
13 | * `expect-errors` expects the compiler to fail, without reporting verification successes and failures,
14 | * `expect-failures` expects the compiler and verifier to run successfully, but reporting one or more verification failures,
15 | * `ignore` causes the test to skip this file.
16 |
17 | These checks are implemented with a regular expression that matches the expected verifier output.
18 |
19 | If no tag is specified on the first line, `expect-success` is assumed.
20 |
21 | The "optional comment" field is _required_ if `ignore` is used.
22 |
23 | It is recommended to include the optional comment if `expect-failures` is used.
24 |
--------------------------------------------------------------------------------
/examples/adts_eq.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs
2 | use builtin_macros::*;
3 | use vstd::*;
4 |
5 | verus! {
6 |
7 | #[derive(PartialEq, Eq)]
8 | struct Thing {}
9 |
10 | #[derive(PartialEq, Eq)]
11 | struct Car {
12 | thing: Thing,
13 | four_doors: bool,
14 | }
15 |
16 | fn one() {
17 | let c1 = Car { thing: Thing { }, four_doors: true };
18 | let c2 = Car { thing: Thing { }, four_doors: true };
19 | assert(c1 == c2);
20 | let t1 = Thing { };
21 | let t2 = Thing { };
22 | assert(t1 == t2);
23 | }
24 |
25 | fn main() {
26 | }
27 |
28 | } // verus!
29 |
--------------------------------------------------------------------------------
/examples/assertions.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs expect-failures
2 | use builtin::*;
3 | use builtin_macros::*;
4 | use vstd::*;
5 |
6 | verus! {
7 |
8 | fn main() {
9 | }
10 |
11 | fn test(b: bool) {
12 | assert(b);
13 | }
14 |
15 | fn has_expectations(b: bool) {
16 | requires(b);
17 | }
18 |
19 | fn fails_expectations() {
20 | has_expectations(false);
21 | }
22 |
23 | fn fails_post()
24 | ensures
25 | false,
26 | {
27 | let x = 5;
28 | let y = 7;
29 | }
30 |
31 | } // verus!
32 |
--------------------------------------------------------------------------------
/examples/assorted_demo.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | #[allow(unused_imports)]
4 | use builtin_macros::*;
5 | #[allow(unused_imports)]
6 | use vstd::*;
7 |
8 | verus! {
9 |
10 | fn main() {
11 | let x = 3;
12 | let y = 4;
13 | assert(x != y);
14 | }
15 |
16 | #[derive(Eq, PartialEq, Structural)]
17 | struct Train {
18 | cars: u64,
19 | }
20 |
21 | fn main2() {
22 | let t = Train { cars: 10 };
23 | let q = Train { cars: 10 };
24 | assert(t == q);
25 | }
26 |
27 | spec fn mul(a: u64, b: u64) -> u64 {
28 | builtin::mul(a, b)
29 | }
30 |
31 | spec fn divides(v: u64, d: u64) -> bool {
32 | exists|k: u64| mul(d, k) == v
33 | }
34 |
35 | #[verifier::external]
36 | fn gcd_external(a: u64, b: u64) -> u64 {
37 | let mut i = a;
38 | while i >= 1 {
39 | if a % i == 0 && b % i == 0 {
40 | break ;
41 | }
42 | i -= 1;
43 | }
44 | i
45 | }
46 |
47 | #[verifier::external_body]
48 | fn gcd(a: u64, b: u64) -> (result: u64)
49 | requires
50 | a >= 0,
51 | b >= 0,
52 | ensures
53 | divides(a, result),
54 | divides(b, result),
55 | {
56 | gcd_external(a, b)
57 | }
58 |
59 | fn main3() {
60 | let x = 42;
61 | let y = 182;
62 | let z = gcd(x, y);
63 | assert(divides(x, z));
64 | assert(divides(y, z));
65 | // TODO assert(x % z == 0);
66 | }
67 |
68 | } // verus!
69 |
--------------------------------------------------------------------------------
/examples/basic_failure.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs expect-failures
2 | #![allow(unused_imports)]
3 | use builtin::*;
4 | use builtin_macros::*;
5 | use vstd::prelude::*;
6 |
7 | verus! {
8 | fn fail_a_post_expr() -> (r: u64)
9 | ensures r == 1
10 | {
11 | 0
12 | }
13 |
14 | fn fail_a_post_stmt(r: &mut u64)
15 | ensures *r == 1
16 | {
17 | *r = 0;
18 | }
19 |
20 | proof fn external_span(s: Seq) {
21 | assert(s[0] == 0);
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/examples/calc.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | #[allow(unused_imports)]
4 | use builtin_macros::*;
5 |
6 | #[allow(unused_imports)]
7 | use vstd::{calc_macro::*, prelude, seq::*, seq_lib::*};
8 |
9 | verus! {
10 |
11 | fn main() {
12 | }
13 |
14 | proof fn calc_example_usage() {
15 | let a: Seq = seq![1u8, 2u8];
16 | let b: Seq = seq![1u8];
17 | let c: Seq = seq![2u8];
18 | let d: Seq = seq![1u8, 2u8];
19 | calc! {
20 | (==)
21 | a; (==) {
22 | assert_seqs_equal!(a == b + c);
23 | }
24 | b + c; {
25 | assert_seqs_equal!(b + c == d);
26 | }
27 | d;
28 | };
29 | calc! {
30 | (<=)
31 | (2 as int); (==) {}
32 | 3 - 1; {}
33 | 5;
34 | };
35 | calc! {
36 | (==>)
37 | (5 > 4); (==) {}
38 | (4 >= 4); (<==>) {}
39 | (2 > 1); (==>) {}
40 | (1 > 0); {}
41 | true;
42 | };
43 | calc! {
44 | (==>)
45 | false; {}
46 | true;
47 | };
48 | }
49 |
50 | } // verus!
51 |
--------------------------------------------------------------------------------
/examples/cargo-verus/library/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "library"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | vstd = { path = "../../../source/vstd", optional = true }
8 | builtin = { path = "../../../source/builtin", optional = true }
9 | builtin_macros = { path = "../../../source/builtin_macros", optional = true }
10 |
11 | [features]
12 | explicit-verus-deps = ["vstd", "builtin", "builtin_macros"]
13 |
14 | [package.metadata.verus]
15 | verify = true
16 |
--------------------------------------------------------------------------------
/examples/cargo-verus/library/src/lib.rs:
--------------------------------------------------------------------------------
1 | use vstd::prelude::*;
2 |
3 | verus! {
4 |
5 | pub fn f() -> (r: u8)
6 | ensures
7 | r == 4,
8 | {
9 | 2 + 2
10 | }
11 |
12 | } // verus!
13 |
--------------------------------------------------------------------------------
/examples/cargo-verus/run.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This script demonstrates the flow enabled by integration with Cargo.
4 | # It requires cargo-verus to be in the current path
5 | # (usually either target-verus/debug or target-verus/release)
6 |
7 | # verify an example without codegen (like cargo check) and without applying rustc (like rust_verify
8 | # without --compile)
9 | cargo verus check --manifest-path test/Cargo.toml -p test
10 |
11 | # verify an example without codegen (like cargo check)
12 | cargo verus verify --manifest-path test/Cargo.toml -p test
13 |
14 | # build and verify an example with codegen (like cargo build)
15 | cargo verus build --manifest-path test/Cargo.toml -p test
16 |
17 | # clean with regular cargo
18 | cargo clean --manifest-path test/Cargo.toml
19 |
20 | # this time with an argument for verus
21 | cargo verus build --manifest-path test/Cargo.toml -p test -- --rlimit=60
22 |
--------------------------------------------------------------------------------
/examples/cargo-verus/test/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "test"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | vstd = { path = "../../../source/vstd" }
8 | builtin = { path = "../../../source/builtin" }
9 | builtin_macros = { path = "../../../source/builtin_macros" }
10 | library = { path = "../library", features = ["explicit-verus-deps"] }
11 |
12 | [package.metadata.verus]
13 | verify = true
14 |
--------------------------------------------------------------------------------
/examples/cargo-verus/test/src/main.rs:
--------------------------------------------------------------------------------
1 | use vstd::{prelude::*, string::*};
2 |
3 | verus! {
4 |
5 | #[verifier::external_body]
6 | fn print_result(value: u32) {
7 | println!("{value}");
8 | }
9 |
10 | fn main() {
11 | let x = library::f();
12 | assert(x == 4);
13 | print_result(x as u32);
14 | }
15 |
16 | } // verus!
17 |
--------------------------------------------------------------------------------
/examples/cells.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | use builtin_macros::*;
4 | use vstd::{cell::*, *};
5 |
6 | verus! {
7 |
8 | struct X {
9 | pub i: u64,
10 | }
11 |
12 | fn main() {
13 | let x = X { i: 5 };
14 | let (pcell, Tracked(mut token)) = PCell::empty();
15 | pcell.put(Tracked(&mut token), x);
16 | assert(token.mem_contents() === MemContents::Init(X { i: 5 }));
17 | }
18 |
19 | } // verus!
20 |
--------------------------------------------------------------------------------
/examples/external.rs:
--------------------------------------------------------------------------------
1 | use builtin::*;
2 | use builtin_macros::*;
3 |
4 | verus! {
5 |
6 | #[verifier::external_body]
7 | fn test(n: u64, s: Ghost)
8 | requires
9 | n > 10 && s@ >= n,
10 | {
11 | println!("hello {}", n);
12 | }
13 |
14 | fn main() {
15 | test(15, Ghost(200));
16 | }
17 |
18 | } // verus!
19 |
--------------------------------------------------------------------------------
/examples/fun_ext.rs:
--------------------------------------------------------------------------------
1 | use vstd::prelude::*;
2 |
3 | verus! {
4 |
5 | fn main() {
6 | }
7 |
8 | proof fn test_funext_specific_1(f1: spec_fn(u8) -> int, f2: spec_fn(u8) -> int)
9 | requires
10 | forall|x: u8| #[trigger] f1(x) == f2(x),
11 | ensures
12 | f1 == f2,
13 | {
14 | assert(f1 =~= f2);
15 | }
16 |
17 | proof fn test_funext_specific_1_alt(f1: spec_fn(u8) -> int, f2: spec_fn(u8) -> int)
18 | requires
19 | forall|x: u8| #[trigger] f1(x) == f2(x),
20 | ensures
21 | f1 == f2,
22 | {
23 | assert(f1 =~= f2);
24 | }
25 |
26 | proof fn test_funext_specific_2(f1: spec_fn(u8, u16) -> int, f2: spec_fn(u8, u16) -> int)
27 | requires
28 | forall|x, y| #[trigger] f1(x, y) == f2(x, y),
29 | ensures
30 | f1 == f2,
31 | {
32 | assert(f1 =~= f2);
33 | }
34 |
35 | } // verus!
36 |
--------------------------------------------------------------------------------
/examples/generics.rs:
--------------------------------------------------------------------------------
1 | use builtin::*;
2 | use builtin_macros::*;
3 |
4 | verus! {
5 |
6 | fn main() {
7 | }
8 |
9 | spec fn f(a1: A, a2: A) -> bool {
10 | true
11 | }
12 |
13 | spec fn id(a: A, b: B, c: A) -> A {
14 | a
15 | }
16 |
17 | fn id_exec(a: A, b: B, c: A) -> (r: A)
18 | requires
19 | f(a, c),
20 | ensures
21 | f(r, a),
22 | {
23 | a
24 | }
25 |
26 | spec fn id_int(i: int) -> int {
27 | id(i, true, 10)
28 | }
29 |
30 | spec fn id_u64(i: u64) -> u64 {
31 | id(i, true, 10)
32 | }
33 |
34 | fn id_u64_exec(i: u64) -> (r: u64)
35 | ensures
36 | f(r, id_u64(i)),
37 | {
38 | id_exec(i, true, 10)
39 | }
40 |
41 | struct S {
42 | n: A,
43 | }
44 |
45 | spec fn s_property(s: S) -> int {
46 | 7
47 | }
48 |
49 | spec fn id_s(s: S) -> S {
50 | id(s, true, s)
51 | }
52 |
53 | proof fn s_prop1(x: S, y: S) {
54 | assert(s_property(x) == s_property(y));
55 | }
56 |
57 | proof fn s_prop2(x: S, y: S) {
58 | assert(s_property(x) == s_property(y));
59 | }
60 |
61 | #[verifier::opaque]
62 | spec fn g(a: A) -> A {
63 | a
64 | }
65 |
66 | proof fn test_g1(u: u8) {
67 | reveal(g::); // REVIEW: should reveal quantify over all A?
68 | assert(g(u) == u);
69 | }
70 |
71 | proof fn test_g2(u: u8) {
72 | assert(g(u) < 256 as int);
73 | }
74 |
75 | } // verus!
76 |
--------------------------------------------------------------------------------
/examples/guide/calc.rs:
--------------------------------------------------------------------------------
1 | use vstd::calc_macro::*;
2 | use vstd::prelude::*;
3 |
4 | verus! {
5 |
6 | fn main() {
7 | }
8 |
9 | proof fn calc_example_simple() {
10 | // ANCHOR: simple
11 | let a: int = 2;
12 | calc! {
13 | (<=)
14 | a; {}
15 | a + 3; {}
16 | 5;
17 | }
18 | // ANCHOR_END: simple
19 | }
20 |
21 | #[verusfmt::skip]
22 | proof fn calc_example_transitive_relations() {
23 | // ANCHOR: transitive
24 | let x: int = 2;
25 | let y: int = 5;
26 | calc! {
27 | (<=)
28 | x; (==) {}
29 | 5 - 3; (<) {}
30 | 5int; {} // Notice that no intermediate relation
31 | // is specified here, so `calc!` will
32 | // use the top-level relation, here `<=`.
33 | y;
34 | }
35 | // ANCHOR_END: transitive
36 | }
37 |
38 | } // verus!
39 |
--------------------------------------------------------------------------------
/examples/guide/equality.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | #[allow(unused_imports)]
4 | use builtin_macros::*;
5 |
6 | verus! {
7 |
8 | // ANCHOR: eq1
9 | fn equal1(x: u8, y: u8) {
10 | let eq1 = x == y; // means x.eq(y) in Rust
11 | let eq2 = y == x; // means y.eq(x) in Rust
12 | assert(eq1 ==> eq2); // succeeds
13 | }
14 | // ANCHOR_END: eq1
15 |
16 | /*
17 | // ANCHOR: eq2
18 | fn equal2(x: A, y: A) {
19 | let eq1 = x == y; // means x.eq(y) in Rust
20 | let eq2 = y == x; // means y.eq(x) in Rust
21 | assert(eq1 ==> eq2); // won't work; we can't be sure that A is an equivalence relation
22 | }
23 | // ANCHOR_END: eq2
24 | */
25 |
26 | // ANCHOR: eq3
27 | fn equal3(x: u8, y: u8) {
28 | assert({
29 | let eq1 = x == y;
30 | let eq2 = y == x;
31 | eq1 ==> eq2
32 | });
33 | }
34 | // ANCHOR_END: eq3
35 |
36 | fn main() {
37 | }
38 |
39 | } // verus!
40 |
--------------------------------------------------------------------------------
/examples/guide/getting_started.rs:
--------------------------------------------------------------------------------
1 | use vstd::prelude::*;
2 |
3 | verus! {
4 |
5 | spec fn min(x: int, y: int) -> int {
6 | if x <= y {
7 | x
8 | } else {
9 | y
10 | }
11 | }
12 |
13 | fn main() {
14 | assert(min(10, 20) == 10);
15 | assert(min(-10, -20) == -20);
16 | assert(forall|i: int, j: int| min(i, j) <= i && min(i, j) <= j);
17 | assert(forall|i: int, j: int| min(i, j) == i || min(i, j) == j);
18 | assert(forall|i: int, j: int| min(i, j) == min(j, i));
19 | }
20 |
21 | } // verus!
22 |
--------------------------------------------------------------------------------
/examples/guide/overflow.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs expect-warnings
2 | #[allow(unused_imports)]
3 | use builtin::*;
4 | #[allow(unused_imports)]
5 | use builtin_macros::*;
6 | use vstd::prelude::*;
7 |
8 | verus! {
9 |
10 | /*
11 | // ANCHOR: compute_sum_fails
12 | fn compute_sum_fails(x: u64, y: u64) -> (result: u64)
13 | ensures
14 | result == x + y,
15 | {
16 | x + y // error: possible arithmetic underflow/overflow
17 | }
18 | // ANCHOR_END: compute_sum_fails
19 | */
20 |
21 | // ANCHOR: compute_sum_limited
22 | fn compute_sum_limited(x: u64, y: u64) -> (result: u64)
23 | requires
24 | x < 1000000,
25 | y < 1000000,
26 | ensures
27 | result == x + y,
28 | {
29 | x + y
30 | }
31 | // ANCHOR_END: compute_sum_limited
32 |
33 | // ANCHOR: compute_sum_runtime_check
34 | fn compute_sum_runtime_check(x: u64, y: u64) -> (result: Option)
35 | ensures
36 | match result {
37 | Some(z) => z == x + y,
38 | None => x + y > u64::MAX,
39 | },
40 | {
41 | x.checked_add(y)
42 | }
43 | // ANCHOR: compute_sum_runtime_check
44 |
45 | fn main() {
46 | }
47 |
48 | } // verus!
49 |
50 |
--------------------------------------------------------------------------------
/examples/guide/pervasive_example.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | #[allow(unused_imports)]
4 | use builtin_macros::*;
5 | use vstd::seq::*;
6 |
7 | verus! {
8 |
9 | fn main() {
10 | proof {
11 | let s: Seq = seq![0, 10, 20, 30, 40];
12 | assert(s.len() == 5);
13 | assert(s[2] == 20);
14 | assert(s[3] == 30);
15 | }
16 | }
17 |
18 | } // verus!
19 |
--------------------------------------------------------------------------------
/examples/guide/requires_ensures.rs:
--------------------------------------------------------------------------------
1 | use vstd::prelude::*;
2 |
3 | verus! {
4 |
5 | #[verifier::external_body]
6 | fn print_two_digit_number(i: i8)
7 | requires
8 | -99 <= i < 100,
9 | {
10 | println!("The answer is {}", i);
11 | }
12 |
13 | fn octuple(x1: i8) -> (x8: i8)
14 | requires
15 | -16 <= x1 < 16,
16 | ensures
17 | x8 == 8 * x1,
18 | {
19 | let x2 = x1 + x1;
20 | let x4 = x2 + x2;
21 | x4 + x4
22 | }
23 |
24 | fn main() {
25 | let n = octuple(10);
26 | assert(n == 80);
27 | print_two_digit_number(n);
28 | }
29 |
30 | } // verus!
31 |
--------------------------------------------------------------------------------
/examples/guide/requires_ensures_edit.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | #[allow(unused_imports)]
4 | use builtin_macros::*;
5 |
6 | verus! {
7 |
8 | /*
9 | // ANCHOR: init
10 | fn octuple(x1: i8) -> i8 {
11 | let x2 = x1 + x1;
12 | let x4 = x2 + x2;
13 | x4 + x4
14 | }
15 | // ANCHOR_END: init
16 |
17 | fn main() {
18 | }
19 |
20 | // ANCHOR: pre1
21 | fn octuple(x1: i8) -> i8
22 | requires
23 | -64 <= x1,
24 | x1 < 64,
25 | {
26 | let x2 = x1 + x1;
27 | let x4 = x2 + x2;
28 | x4 + x4
29 | }
30 | // ANCHOR_END: pre1
31 |
32 | fn main() {
33 | }
34 |
35 | // ANCHOR: pre2
36 | fn octuple(x1: i8) -> i8
37 | requires
38 | -16 <= x1,
39 | x1 < 16,
40 | {
41 | let x2 = x1 + x1;
42 | let x4 = x2 + x2;
43 | x4 + x4
44 | }
45 | // ANCHOR_END: pre2
46 |
47 | fn main() {
48 | }
49 |
50 | // ANCHOR: pre3
51 | fn main() {
52 | let n = octuple(20);
53 | }
54 | // ANCHOR_END: pre3
55 |
56 | // ANCHOR: pre4
57 | fn main() {
58 | let n = octuple(10);
59 | }
60 | // ANCHOR_END: pre4
61 | */
62 |
63 | // ANCHOR: post1
64 | fn main() {
65 | let n = octuple(10);
66 | assert(n == 80);
67 | }
68 | // ANCHOR_END: post1
69 |
70 | // ANCHOR: post2
71 | fn octuple(x1: i8) -> (x8: i8)
72 | requires
73 | -16 <= x1,
74 | x1 < 16,
75 | ensures
76 | x8 == 8 * x1,
77 | {
78 | let x2 = x1 + x1;
79 | let x4 = x2 + x2;
80 | x4 + x4
81 | }
82 | // ANCHOR_END: post2
83 |
84 | } // verus!
85 |
--------------------------------------------------------------------------------
/examples/invariants.rs:
--------------------------------------------------------------------------------
1 | #![allow(unused_imports)]
2 |
3 | use vstd::prelude::*;
4 | use vstd::invariant::*;
5 |
6 | verus! {
7 |
8 | struct ModPredicate {}
9 |
10 | impl InvariantPredicate for ModPredicate {
11 | closed spec fn inv(k: int, v: u32) -> bool {
12 | v as int % 2 == k
13 | }
14 | }
15 |
16 | pub fn main() {
17 | let tracked u: u32 = 5u32;
18 | let tracked i: AtomicInvariant = AtomicInvariant::new(1, u, 0);
19 | open_atomic_invariant!(&i => inner => {
20 | proof {
21 | if inner == 1u32 {
22 | inner = 3u32;
23 | }
24 | }
25 | });
26 | let tracked j: AtomicInvariant = AtomicInvariant::new(1, 7u32, 1);
27 | open_atomic_invariant!(&i => inner_i => {
28 | open_atomic_invariant!(&j => inner_j => {
29 | proof {
30 | let tracked tmp = inner_i;
31 | inner_i = inner_j;
32 | inner_j = tmp;
33 | }
34 | });
35 | });
36 | let tracked j = i.into_inner();
37 | assert(j % 2 == 1);
38 | }
39 |
40 | } // verus!
41 |
--------------------------------------------------------------------------------
/examples/modules.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | #[allow(unused_imports)]
4 | use builtin_macros::*;
5 |
6 | verus! {
7 |
8 | fn main() {
9 | }
10 |
11 | mod M1 {
12 | use builtin::*;
13 |
14 | spec fn f1(i: int) -> int {
15 | i + 1
16 | }
17 |
18 | pub closed spec fn f2(i: int) -> int {
19 | f1(i) + 1
20 | }
21 |
22 | }
23 |
24 | mod M2 {
25 | use crate::M1::f2;
26 | #[allow(unused_imports)]
27 | use builtin::*;
28 |
29 | proof fn P() {
30 | // assert(f2(10) == 12); // FAILS, since f2 is closed (abstract)
31 | assert(f2(10) == f2(10));
32 | }
33 |
34 | }
35 |
36 | } // verus!
37 |
--------------------------------------------------------------------------------
/examples/pcm/main.rs:
--------------------------------------------------------------------------------
1 | #![allow(unused_imports)]
2 | use builtin::*;
3 | use builtin_macros::*;
4 | use vstd::prelude::*;
5 |
6 | pub mod agreement;
7 | pub mod log;
8 | pub mod monotonic_counter;
9 | pub mod oneshot;
10 |
11 | verus! {
12 |
13 | pub fn main() {
14 | }
15 |
16 | } // verus!
17 |
--------------------------------------------------------------------------------
/examples/playground.rs:
--------------------------------------------------------------------------------
1 | use builtin::*;
2 | use builtin_macros::*;
3 |
4 | verus! {
5 |
6 | #[derive(PartialEq, Eq, Structural)]
7 | struct S {
8 | a: A,
9 | b: bool,
10 | }
11 |
12 | fn add1(a: &mut u32)
13 | requires
14 | *old(a) < 10,
15 | ensures
16 | *a == *old(a) + 1,
17 | {
18 | *a = *a + 1;
19 | }
20 |
21 | fn foo(s: S) {
22 | // let mut s = s;
23 | let mut s = S { a: 5, b: false };
24 | add1(&mut s.a);
25 | assert(s.a == 6);
26 | assert(s.b == false);
27 | assert(s == S { a: 6u32, b: false });
28 | }
29 |
30 | // The following causes a trigger loop (useful for testing rlimit-related features):
31 | //
32 | // spec fn f(x: nat, y: nat) -> bool;
33 | //
34 | // proof fn goodbye_z3()
35 | // requires forall|x: nat, y: nat| f(x + 1, 2 * y) && f(2 * x, y + x) || f(y, x) ==> (#[trigger] f(x, y)),
36 | // ensures forall|x: nat, y: nat| x > 2318 && y < 100 ==> f(x, y),
37 | // {
38 | // }
39 | fn main() {
40 | }
41 |
42 | } // verus!
43 |
--------------------------------------------------------------------------------
/examples/prelude.rs:
--------------------------------------------------------------------------------
1 | #[allow(unused_imports)]
2 | use builtin::*;
3 | #[allow(unused_imports)]
4 | use builtin_macros::*;
5 | use vstd::prelude::*;
6 |
7 | verus! {
8 |
9 | proof fn lemma() {
10 | let a: Seq = seq![1, 2, 3];
11 | assert(a[1] == 2);
12 | }
13 |
14 | fn main() {
15 | }
16 |
17 | } // verus!
18 |
--------------------------------------------------------------------------------
/examples/set_from_vec.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(verus_keep_ghost, verifier::exec_allows_no_decreases_clause)]
2 | use vstd::prelude::*;
3 |
4 | verus! {
5 |
6 | struct VecSet {
7 | vt: Vec,
8 | }
9 |
10 | impl VecSet {
11 | pub closed spec fn view(&self) -> Set {
12 | self.vt@.to_set()
13 | }
14 |
15 | pub fn new() -> (s: Self)
16 | ensures
17 | s@ =~= Set::::empty(),
18 | {
19 | VecSet { vt: Vec::new() }
20 | }
21 |
22 | pub fn insert(&mut self, v: u64)
23 | ensures
24 | self@ =~= old(self)@.insert(v),
25 | {
26 | self.vt.push(v);
27 | proof {
28 | broadcast use vstd::seq_lib::group_seq_properties;
29 | }
30 | assert(self.vt@ =~= old(self).vt@ + seq![v]);
31 | }
32 |
33 | pub fn contains(&self, v: u64) -> (contained: bool)
34 | ensures
35 | contained == self@.contains(v),
36 | {
37 | for i in iter: 0..self.vt.len()
38 | invariant
39 | forall|j: nat| j < i ==> self.vt[j as int] != v,
40 | {
41 | if self.vt[i] == v {
42 | return true;
43 | }
44 | }
45 | false
46 | }
47 | }
48 |
49 | fn main() {
50 | let mut vs: VecSet = VecSet::new();
51 | assert(vs@ =~= set![]);
52 | vs.insert(3);
53 | vs.insert(5);
54 | let contains2 = vs.contains(2);
55 | assert(!contains2);
56 | assert(vs@ =~= set![3, 5]);
57 | }
58 |
59 | } // verus!
60 |
--------------------------------------------------------------------------------
/examples/state_machines/adder.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs expect-warnings
2 | #[allow(unused_imports)]
3 | use builtin::*;
4 | use builtin_macros::*;
5 | use vstd::{pervasive::*, *};
6 |
7 | use state_machines_macros::state_machine;
8 |
9 | verus! {
10 |
11 | state_machine!(
12 | X {
13 | fields {
14 | pub number: int,
15 | }
16 |
17 | init!{
18 | initialize() {
19 | let x = 5 + 9;
20 | init number = 0;
21 | }
22 | }
23 |
24 | transition!{
25 | add(n: int) {
26 | require n == 0;
27 | update number = pre.number + 2*n;
28 | }
29 | }
30 |
31 | #[invariant]
32 | pub fn is_even(&self) -> bool {
33 | self.number % 2 == 0
34 | }
35 |
36 | #[inductive(initialize)]
37 | fn initialize_inductive(post: Self) { }
38 |
39 | #[inductive(add)]
40 | fn add_inductive(pre: Self, post: Self, n: int) {
41 | }
42 |
43 | }
44 | );
45 |
46 | } // verus!
47 | fn main() {}
48 |
--------------------------------------------------------------------------------
/examples/state_machines/adder_generic.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs expect-warnings
2 | #[allow(unused_imports)]
3 | use builtin::*;
4 | use vstd::{pervasive::*, *};
5 |
6 | use state_machines_macros::state_machine;
7 |
8 | state_machine!(
9 | X {
10 | fields {
11 | pub number: int,
12 | pub t: T,
13 | }
14 |
15 | init!{
16 | initialize(t: T) {
17 | init number = 0;
18 | init t = t;
19 | }
20 | }
21 |
22 | transition!{
23 | add(n: int) {
24 | update number = pre.number + 2*n;
25 | }
26 | }
27 |
28 | #[invariant]
29 | pub fn is_even(&self) -> bool {
30 | self.number % 2 == 0
31 | }
32 |
33 | #[inductive(initialize)]
34 | fn init_preserves(post: Self, t: T) {
35 | }
36 |
37 | #[inductive(add)]
38 | fn add_preserves(pre: Self, post: Self, n: int) {
39 | }
40 | }
41 | );
42 |
43 | fn main() {}
44 |
--------------------------------------------------------------------------------
/examples/state_machines/tutorial/unverified_counting_to_n:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/examples/state_machines/tutorial/unverified_counting_to_n
--------------------------------------------------------------------------------
/examples/statements.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(verus_keep_ghost, verifier::exec_allows_no_decreases_clause)]
2 | use builtin::*;
3 | use builtin_macros::*;
4 |
5 | verus! {
6 |
7 | fn main() {
8 | }
9 |
10 | fn test_if(b: bool) {
11 | let mut x: u32 = 0;
12 | if b {
13 | x = 10;
14 | }
15 | assert(b ==> x == 10);
16 | if b {
17 | x = x + 3;
18 | x = x + 4;
19 | } else {
20 | x = x + 2;
21 | }
22 | assert(b ==> x == 17);
23 | assert(!b ==> x == 2);
24 | assert(x == if b {
25 | 17int
26 | } else {
27 | 2
28 | });
29 | if x == 0 {
30 | assert(false);
31 | } else if x == 1 {
32 | assert(false);
33 | } else if x == 2 {
34 | assert(!b);
35 | } else {
36 | assert(x == 17);
37 | }
38 | }
39 |
40 | fn test_loop() {
41 | let mut i: u64 = 10;
42 | let mut b1: u8 = 20;
43 | let mut b2: u8 = 200;
44 | let mut b3: u8 = 30;
45 | while i < 100
46 | invariant
47 | 10 <= i,
48 | i <= 100,
49 | b1 == i * 2,
50 | {
51 | assert(b2 <= 255);
52 | i = i + 1;
53 | b1 = b1 + 2;
54 | b2 = b2 / 2;
55 | }
56 | assert(b1 == 200);
57 | assert(b3 == 30);
58 | }
59 |
60 | } // verus!
61 |
--------------------------------------------------------------------------------
/examples/std_test/option_test.rs:
--------------------------------------------------------------------------------
1 | use std::option::Option::{None, Some};
2 |
3 | use vstd::pervasive::runtime_assert;
4 | use vstd::prelude::*;
5 |
6 | verus! {
7 |
8 | fn is_some_test() {
9 | let a: Option = None;
10 | let b = Some(2);
11 | runtime_assert(!a.is_some());
12 | runtime_assert(b.is_some());
13 | }
14 |
15 | fn is_none_test() {
16 | let a: Option = None;
17 | let b = Some(2);
18 | runtime_assert(a.is_none());
19 | runtime_assert(!b.is_none());
20 | }
21 |
22 | fn as_ref_test() {
23 | let a = Option::Some(2);
24 | if let Some(ref_val) = a.as_ref() {
25 | runtime_assert(*ref_val == 2);
26 | } else {
27 | runtime_assert(false);
28 | }
29 | }
30 |
31 | fn unwrap_test() {
32 | let a = Option::Some(2);
33 | let b = Option::Some(4);
34 | runtime_assert(a.unwrap() == 2);
35 | runtime_assert(a.unwrap() != b.unwrap());
36 | }
37 |
38 | fn unwrap_or_test() {
39 | let a = Option::Some(2);
40 | let b = Option::None;
41 | runtime_assert(a.unwrap_or(3) == 2);
42 | runtime_assert(b.unwrap_or(3) == 3);
43 | }
44 |
45 | fn ok_or_test() {
46 | let a: Option = Option::Some(2);
47 | let b: Option = Option::None;
48 | let ra: Result = a.ok_or(false);
49 | let rb: Result = b.ok_or(false);
50 | assert(ra.is_ok());
51 | assert(ra.unwrap() == 2);
52 | assert(rb.is_err());
53 | assert(rb.unwrap_err() == false);
54 | }
55 |
56 | } // verus!
57 |
--------------------------------------------------------------------------------
/examples/std_test/rc_test.rs:
--------------------------------------------------------------------------------
1 | use std::rc::Rc;
2 |
3 | use vstd::pervasive::runtime_assert;
4 | use vstd::prelude::*;
5 |
6 | verus! {
7 |
8 | fn try_unwrap_test() {
9 | let r1 = Rc::new(5);
10 | let r2 = r1.clone();
11 | let result1 = Rc::try_unwrap(r1);
12 | assert(result1 is Err ==> result1.unwrap_err() == 5);
13 | match result1 {
14 | Err(r3) => { runtime_assert(*r3 == 5); },
15 | Ok(five) => { assert(five == 5); }, // won't happen
16 | };
17 | let result2 = Rc::try_unwrap(r2);
18 | assert(result2 is Ok ==> result2.unwrap() == 5);
19 | match result2 {
20 | Err(r4) => { assert(r4 == 5); }, // won't happen
21 | Ok(five) => { runtime_assert(five == 5); },
22 | }
23 |
24 | }
25 |
26 | fn into_inner_test() {
27 | let r1 = Rc::new(5);
28 | let r2 = r1.clone();
29 | let result1 = Rc::into_inner(r1);
30 | match result1 {
31 | Some(five) => {
32 | assert(five == 5); // won't happen
33 | },
34 | None => {
35 | let result2 = Rc::into_inner(r2);
36 | match result2 {
37 | Some(five) => { runtime_assert(five == 5) },
38 | None => {},
39 | }
40 | },
41 | }
42 | }
43 |
44 | } // verus!
45 |
--------------------------------------------------------------------------------
/examples/std_test/template.rs:
--------------------------------------------------------------------------------
1 | use vstd::pervasive::runtime_assert;
2 | use vstd::prelude::*;
3 |
4 | verus! {
5 |
6 | fn a_test() {
7 | let a = 2;
8 | let b = 3;
9 | runtime_assert(a + b == 5);
10 | }
11 |
12 | } // verus!
13 |
--------------------------------------------------------------------------------
/examples/std_test/vec_test.rs:
--------------------------------------------------------------------------------
1 | use std::vec::Vec;
2 |
3 | use vstd::pervasive::runtime_assert;
4 | use vstd::prelude::*;
5 |
6 | verus! {
7 |
8 | fn vec_extend_slice_test() {
9 | let mut a: Vec = vec![1, 2];
10 | let b: Vec = vec![3, 4];
11 | a.extend_from_slice(b.as_slice());
12 | runtime_assert(a.len() == 4);
13 | runtime_assert(a[0] == 1);
14 | runtime_assert(a[1] == 2);
15 | runtime_assert(a[2] == 3);
16 | runtime_assert(a[3] == 4);
17 | runtime_assert(b.len() == 2);
18 | }
19 |
20 | } // verus!
21 |
--------------------------------------------------------------------------------
/examples/structural.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs
2 | use builtin_macros::*;
3 |
4 | verus! {
5 |
6 | #[derive(PartialEq, Eq, Structural)]
7 | struct Thing {}
8 |
9 | #[derive(PartialEq, Eq, Structural)]
10 | struct Car {
11 | passengers: T,
12 | four_doors: bool,
13 | }
14 |
15 | fn one() {
16 | let c1 = Car { passengers: Thing { }, four_doors: true };
17 | let c2 = Car { passengers: Thing { }, four_doors: true };
18 | assert(c1 == c2);
19 | }
20 |
21 | fn two(c1: Car, c2: Car) {
22 | if c1 == c2 {
23 | assert(c1 == c2);
24 | }
25 | }
26 |
27 | fn main() {
28 | }
29 |
30 | } // verus!
31 |
--------------------------------------------------------------------------------
/examples/summer_school/chapter-2-2.rs:
--------------------------------------------------------------------------------
1 | #![cfg_attr(verus_keep_ghost, verifier::exec_allows_no_decreases_clause)]
2 | #[allow(unused_imports)]
3 | use prelude::*;
4 | #[allow(unused_imports)]
5 | use seq::*;
6 | use vstd::prelude::*;
7 | #[allow(unused_imports)]
8 | use vstd::*;
9 |
10 | verus! {
11 |
12 | spec fn divides(factor: nat, candidate: nat) -> bool
13 | recommends
14 | 1 <= factor,
15 | {
16 | candidate % factor == 0
17 | }
18 |
19 | spec fn is_prime(candidate: nat) -> bool {
20 | &&& 1 < candidate
21 | &&& forall|factor: nat| 1 < factor < candidate ==> !divides(factor, candidate)
22 | }
23 |
24 | fn test_prime(candidate: u64) -> (result: bool)
25 | requires
26 | 1 < candidate,
27 | ensures
28 | result == is_prime(candidate as nat),
29 | {
30 | let mut factor: u64 = 2;
31 | while factor < candidate
32 | invariant
33 | 1 < factor,
34 | forall|smallerfactor: nat|
35 | 1 < smallerfactor < factor ==> !divides(smallerfactor, candidate as nat),
36 | {
37 | if candidate % factor == 0 {
38 | assert(divides(factor as nat, candidate as nat));
39 | return false;
40 | }
41 | factor = factor + 1;
42 | }
43 | true
44 | }
45 |
46 | fn main() {
47 | }
48 |
49 | } // verus!
50 |
--------------------------------------------------------------------------------
/examples/test.rs:
--------------------------------------------------------------------------------
1 | use builtin::*;
2 | use builtin_macros::*;
3 |
4 | verus! {
5 |
6 | pub fn foo(a: u64) -> u64
7 | requires
8 | a < 100,
9 | {
10 | a + 1
11 | }
12 |
13 | fn main() {
14 | let c = 1;
15 | let mut b = 3;
16 | b = 4;
17 | b = foo(c);
18 | }
19 |
20 | } // verus!
21 |
--------------------------------------------------------------------------------
/examples/thread.rs:
--------------------------------------------------------------------------------
1 | // rust_verify/tests/example.rs
2 | #[allow(unused_imports)]
3 | use builtin::*;
4 | #[allow(unused_imports)]
5 | use builtin_macros::*;
6 | use vstd::thread::*;
7 |
8 | verus! {
9 |
10 | fn test_calling_thread_id_twice_same_value() {
11 | let (tid1, Tracked(is1)) = thread_id();
12 | let (tid2, Tracked(is2)) = thread_id();
13 | proof {
14 | is1.agrees(is2);
15 | }
16 | assert(tid1 == tid2);
17 | }
18 |
19 | fn test_calling_thread_id_twice_diff_threads() {
20 | let (tid1, Tracked(is1)) = thread_id();
21 | spawn(
22 | move ||
23 | {
24 | let (tid2, Tracked(is2)) = thread_id();
25 | // This isn't allowed: Send error
26 | /*proof {
27 | is1.agrees(is2);
28 | }*/
29 | },
30 | );
31 | }
32 |
33 | } // verus!
34 | fn main() {}
35 |
--------------------------------------------------------------------------------
/examples/trait_for_fn.rs:
--------------------------------------------------------------------------------
1 | use vstd::prelude::*;
2 |
3 | verus! {
4 |
5 | trait IntFn {
6 | spec fn call_int(&self, x: int) -> int;
7 | }
8 |
9 | impl IntFn for spec_fn(int) -> int {
10 | spec fn call_int(&self, x: int) -> int {
11 | self(x)
12 | }
13 | }
14 |
15 | proof fn use_IntFn() {
16 | let f: spec_fn(int) -> int = |x: int| x + 1;
17 | assert(f.call_int(2) == 3);
18 | }
19 |
20 | fn main() {
21 | }
22 |
23 | } // verus!
24 |
--------------------------------------------------------------------------------
/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | channel = "1.85.1"
3 | # channel = "nightly-2023-09-29" # TODO update to match 1.84.0 (not officially supported)
4 | components = [ "rustc", "rust-std", "cargo", "rustfmt", "rustc-dev", "llvm-tools" ]
5 |
--------------------------------------------------------------------------------
/source/.envrc:
--------------------------------------------------------------------------------
1 | source ../tools/activate
2 |
--------------------------------------------------------------------------------
/source/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | /z3
3 | /cvc5
4 | /.verus-log/
5 | doc/
6 | /target-verus/
7 |
--------------------------------------------------------------------------------
/source/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | resolver = "2"
3 | members = [
4 | "air",
5 | "builtin",
6 | "builtin_macros",
7 | "cargo-verus",
8 | "vir",
9 | "vir_macros",
10 | "rust_verify",
11 | "verus",
12 | "rust_verify_test",
13 | "rust_verify_test_macros",
14 | "state_machines_macros",
15 | "verusdoc",
16 | "vstd_build",
17 | "tools/internals_interface",
18 | "tools/line_count",
19 | "tools/qi-graph",
20 | ]
21 | exclude = [
22 | "vstd",
23 | ]
24 |
25 | # do not modify the following two lines
26 | [workspace.metadata.vargo]
27 | tag = "workspace"
28 |
--------------------------------------------------------------------------------
/source/air/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "air"
3 | version = "0.1.0"
4 | edition = "2018"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | # Note: do not add any dependencies on rustc -- AIR deliberately abstracts away from rustc's internals
9 | [dependencies]
10 | sise = "0.6.0"
11 | getopts = { git = "https://github.com/utaal/getopts.git", branch = "parse-partial" }
12 | z3tracer = { git = "https://github.com/verus-lang/smt2utils.git", rev = "ec4c894d04d7cd39c9a8aa1eda51db71cc54fe61" }
13 | serde = { version = "1", features = ["derive", "rc"] }
14 | indexmap = { version = "1" }
15 | yansi = "0.5"
16 |
17 | [target.'cfg(windows)'.dependencies]
18 | win32job = "1"
19 |
20 | [features]
21 | singular = []
22 |
--------------------------------------------------------------------------------
/source/air/src/def.rs:
--------------------------------------------------------------------------------
1 | use crate::ast::Ident;
2 | use std::sync::Arc;
3 |
4 | pub const PREFIX_LABEL: &str = "%%location_label%%";
5 | pub const GLOBAL_PREFIX_LABEL: &str = "%%global_location_label%%";
6 | const BREAK_LABEL: &str = "%%break_label%%";
7 | pub const SWITCH_LABEL: &str = "%%switch_label%%";
8 | pub const FUNCTION: &str = "%%Function%%";
9 | pub const ARRAY: &str = "%%array%%";
10 | pub const LAMBDA: &str = "%%lambda%%";
11 | pub const CHOOSE: &str = "%%choose%%";
12 | pub const HOLE: &str = "%%hole%%";
13 | pub const APPLY: &str = "%%apply%%";
14 | pub const TEMP: &str = "%%x%%";
15 | pub const SKOLEM_ID_PREFIX: &str = "skolem";
16 | pub const ARRAY_QID: &str = "__AIR_ARRAY_QID__";
17 |
18 | pub fn mk_skolem_id(qid: &str) -> String {
19 | format!("{}_{}", crate::def::SKOLEM_ID_PREFIX, qid)
20 | }
21 |
22 | pub(crate) fn break_label(label: &Ident) -> Ident {
23 | Arc::new(format!("{}{}", BREAK_LABEL, label))
24 | }
25 |
--------------------------------------------------------------------------------
/source/air/src/lib.rs:
--------------------------------------------------------------------------------
1 | pub mod ast;
2 | pub mod ast_util;
3 | pub mod context;
4 | pub mod emitter;
5 | pub mod focus;
6 | pub mod messages;
7 | pub mod model;
8 | pub mod parser;
9 | pub mod profiler;
10 | pub mod scope_map;
11 | pub mod smt_process;
12 |
13 | #[macro_use]
14 | pub mod printer;
15 |
16 | mod block_to_assert;
17 | mod closure;
18 | mod def;
19 | mod smt_verify;
20 | mod tests;
21 | mod typecheck;
22 | mod util;
23 | mod var_to_const;
24 | mod visitor;
25 |
26 | #[cfg(feature = "singular")]
27 | pub mod singular_manager;
28 |
--------------------------------------------------------------------------------
/source/air/src/util.rs:
--------------------------------------------------------------------------------
1 | pub(crate) fn vec_map B>(v: &Vec, f: F) -> Vec {
2 | v.iter().map(f).collect::>()
3 | }
4 |
--------------------------------------------------------------------------------
/source/builtin/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "builtin"
3 | version = "0.1.0"
4 | edition = "2018"
5 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
6 |
7 | [package.metadata.verus]
8 | is-builtin = true
9 |
10 | [lints.rust]
11 | unexpected_cfgs = { level = "warn", check-cfg = [
12 | 'cfg(verus_keep_ghost)',
13 | 'cfg(verus_verify_core)',
14 | ] }
15 |
--------------------------------------------------------------------------------
/source/builtin_macros/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "builtin_macros"
3 | version = "0.1.0"
4 | edition = "2018"
5 |
6 | [lib]
7 | proc-macro = true
8 |
9 | [dependencies]
10 | proc-macro2 = "1.0.39"
11 | quote = "1.0"
12 | synstructure = { git = "https://github.com/mystor/synstructure.git", rev = "1079497eb2bea252433dac53afe41291d8779641" }
13 | syn = { version = "2.0", features = ["full", "visit", "visit-mut", "extra-traits"] }
14 | syn_verus = { path="../../dependencies/syn", features = ["full", "visit", "visit-mut", "extra-traits"] }
15 | prettyplease_verus = { path="../../dependencies/prettyplease" }
16 |
17 | [package.metadata.verus]
18 | is-builtin-macros = true
19 |
20 | [lints.rust]
21 | unexpected_cfgs = { level = "warn", check-cfg = ['cfg(verus_keep_ghost)'] }
22 |
23 | [features]
24 | vpanic = []
--------------------------------------------------------------------------------
/source/builtin_macros/src/fndecl.rs:
--------------------------------------------------------------------------------
1 | use proc_macro2::TokenStream;
2 | use quote::quote;
3 |
4 | #[inline(always)]
5 | pub fn fndecl(input: TokenStream) -> TokenStream {
6 | quote! {
7 | #[verifier::spec] #[verifier::external_body] /* vattr */ #input { unimplemented!() }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/source/builtin_macros/src/structural.rs:
--------------------------------------------------------------------------------
1 | use syn_verus::spanned::Spanned;
2 |
3 | pub fn derive_structural(mut s: synstructure::Structure) -> proc_macro2::TokenStream {
4 | let assert_receiver_is_structural_body = s
5 | .variants()
6 | .iter()
7 | .flat_map(|v| v.ast().fields)
8 | .map(|f| {
9 | let ty = &f.ty;
10 | quote_spanned_builtin! { builtin, ty.span() =>
11 | let _: #builtin::AssertParamIsStructural<#ty>;
12 | }
13 | })
14 | .collect::();
15 |
16 | // TODO: this feature has disappeared in the latest version of synstructure
17 | // (this is why we still use a specific commit of synstructure)
18 | // see 'path.segments.iter().find(|s| s.starts_with("_DERIVE_builtin_Structural_FOR_")).is_some()' in rust_to_vir
19 | s.underscore_const(false);
20 |
21 | s.gen_impl(quote_spanned_builtin! { builtin, s.ast().span() =>
22 | #[automatically_derived]
23 | #[allow(non_local_definitions)]
24 | gen unsafe impl #builtin::Structural for @Self {
25 | #[inline]
26 | #[doc(hidden)]
27 | fn assert_receiver_is_structural(&self) -> () {
28 | #assert_receiver_is_structural_body
29 | }
30 | }
31 | })
32 | }
33 |
--------------------------------------------------------------------------------
/source/cargo-verus/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cargo-verus"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | cargo_metadata = "0.18.1"
8 | rustc_tools_util = "0.3.0"
9 | anyhow = "1.0"
10 | serde = { version = "1.0", features = ["derive"] }
11 | serde_json = "1.0"
12 | sha2 = "0.10.2"
13 | hex = "0.4.3"
14 | colored = "3.0.0"
15 |
16 | [build-dependencies]
17 | rustc_tools_util = "0.3.0"
18 |
--------------------------------------------------------------------------------
/source/cargo-verus/build.rs:
--------------------------------------------------------------------------------
1 | //
2 | // Copyright (c) 2024 The Verus Contributors
3 | //
4 | // SPDX-License-Identifier: MIT
5 | //
6 |
7 | fn main() {
8 | rustc_tools_util::setup_version_info!();
9 |
10 | // See https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed
11 | println!("cargo:rerun-if-changed=build.rs");
12 | }
13 |
--------------------------------------------------------------------------------
/source/docs/guide/.gitignore:
--------------------------------------------------------------------------------
1 | book
2 | *.swp
3 |
--------------------------------------------------------------------------------
/source/docs/guide/README.md:
--------------------------------------------------------------------------------
1 | # Requirements
2 |
3 | To build the guide locally, you will need to install [mdBook](https://rust-lang.github.io/mdBook/).
4 | The simplest approach is often to run `cargo install mdbook`.
5 |
6 | # Building
7 |
8 | To build the guide, run `mdbook serve`. This will render the guide
9 | and start a local webserver where you can view your updated guide.
10 |
--------------------------------------------------------------------------------
/source/docs/guide/book.toml:
--------------------------------------------------------------------------------
1 | [book]
2 | language = "en"
3 | multilingual = false
4 | src = "src"
5 | title = "Verus Tutorial and Reference"
6 |
7 | [rust]
8 | edition = "2018"
9 |
10 | [output.html]
11 | curly-quotes = true
12 |
13 | [output.html.playground]
14 | runnable = false
15 |
--------------------------------------------------------------------------------
/source/docs/guide/src/break.md:
--------------------------------------------------------------------------------
1 | # Loops with break
2 |
3 | Loops can exit early using `return` or `break`.
4 | Suppose, for example, we want to remove the requirement
5 | `triangle(n as nat) < 0x1_0000_0000` from the `loop_triangle` function,
6 | and instead check for overflow at run-time.
7 | The following version of the function uses `return` to return
8 | the special value `0xffff_ffff` in case overflow is detected at run-time:
9 |
10 | ```rust
11 | {{#include ../../../../examples/guide/recursion.rs:loop_return}}
12 | ```
13 |
14 | Another way to exit early from a loop is with a `break` inside the loop body.
15 | However, `break` complicates the specification of a loop slightly.
16 | For simple `while` loops without a `break`,
17 | Verus knows that the loop condition (e.g. `idx < n`)
18 | must be false after exiting the loop.
19 | If there is a `break`, though, the loop condition is not necessarily false
20 | after the loop, because the `break` might cause the loop to exit even when
21 | the loop condition is true.
22 | To deal with this, `while` loops with a `break`,
23 | as well as Rust `loop` expressions (loops with no condition),
24 | must explicitly specify what is true after the loop exit using `ensures` clauses,
25 | as shown in the following code.
26 | Furthermore, invariants that don't hold after a `break`
27 | must be marked as `invariant_except_break` rather than `invariant`:
28 |
29 | ```rust
30 | {{#include ../../../../examples/guide/recursion.rs:loop_break}}
31 | ```
32 |
--------------------------------------------------------------------------------
/source/docs/guide/src/char.md:
--------------------------------------------------------------------------------
1 | # The `char` primitive
2 |
3 | Citing the [Rust documentation on `char`](https://doc.rust-lang.org/std/primitive.char.html):
4 |
5 | > A char is a ‘Unicode scalar value’, which is any ‘Unicode code point’ other than a surrogate code point. This has a fixed numerical definition: code points are in the range 0 to 0x10FFFF, inclusive. Surrogate code points, used by UTF-16, are in the range 0xD800 to 0xDFFF.
6 |
7 | Verus treats `char` similarly to bounded integer primitives like `u64` or `u32`: We represent
8 | `char` as an integer. A `char` always carries an invariant that it is in the prescribed set
9 | of allowed values:
10 |
11 | `[0, 0xD7ff] ∪ [0xE000, 0x10FFFF]`
12 |
13 | In spec code, chars can be [cast to and from other integer types using `as`](./reference-as.md).
14 | This is more
15 | permissive than exec code, which disallows many of these coercions.
16 | As with other coercions, the result may be undefined if the integer being coerced does not
17 | fit in the target range.
18 |
--------------------------------------------------------------------------------
/source/docs/guide/src/complex_ownership.md:
--------------------------------------------------------------------------------
1 | # Unsafe code & complex ownership
2 |
3 | Here we discuss the handling of more complex patterns relating to Rust ownership including:
4 |
5 | * Interior mutability, where Rust allows you to mutate data even through a shared reference `&T`
6 | * Raw pointers, which require proper ownership handling in order to uphold safety contracts
7 | * Concurrency, where objects owned across different threads may need to coordinate.
8 |
--------------------------------------------------------------------------------
/source/docs/guide/src/concurrency.md:
--------------------------------------------------------------------------------
1 | # Concurrency
2 |
3 | Verus provides the _VerusSync framework_
4 | for verifing programs that require a nontrivial ownership discipline.
5 | This includes *multi-threaded concurrent code*, and frequently it is also needed for nontrivial
6 | applications of unsafe features (such as pointers or unsafe cells).
7 |
8 | The topic is sufficiently complex that we cover it in a
9 | [separate tutorial and reference book](https://verus-lang.github.io/verus/state_machines/intro.html).
10 |
11 |
--------------------------------------------------------------------------------
/source/docs/guide/src/const.md:
--------------------------------------------------------------------------------
1 | # const declarations
2 |
3 | `const` declarations can either be marked `spec` or left without a mode:
4 |
5 | ```rust
6 | {{#include ../../../../examples/guide/modes.rs:const1}}
7 | ```
8 |
9 | A `spec const` is like `spec` function with no arguments.
10 | It is always ghost and cannot be used as an `exec` value.
11 |
12 | By contrast, a `const` without a mode is dual-use:
13 | it is usable as both an `exec` value and a `spec` value.
14 | Therefore, the `const` definition is restricted to obey the rules
15 | for both `exec` code and `spec` code.
16 | For example, as with `exec` code, its type must be compilable (e.g. `u8`, not `int`),
17 | and, as with `spec` code, it cannot call any `exec` or `proof` functions.
18 |
--------------------------------------------------------------------------------
/source/docs/guide/src/container_bst.md:
--------------------------------------------------------------------------------
1 | # Verifying a container library
2 |
3 | In this section, we'll learn how to verify a simple container library, specifically,
4 | via an example of a _map_ data structure implemented using a binary search tree.
5 | In the case study, we'll explore various considerations for
6 | writing a modular specification
7 | that encapsulates verification details as well as implementation details.
8 |
--------------------------------------------------------------------------------
/source/docs/guide/src/container_bst_all_source.md:
--------------------------------------------------------------------------------
1 | # Full source for the examples
2 |
3 | * [First draft](#first-draft)
4 | * [Version with type invariants](#version-with-type-invariants)
5 | * [Version with generic key type and Clone implementation](#version-with-generic-key-type-and-clone-implementation)
6 |
7 | ## First draft
8 |
9 | ```rust
10 | {{#include ../../../../examples/guide/bst_map.rs:all}}
11 | ```
12 |
13 | ## Version with type invariants
14 |
15 | ```rust
16 | {{#include ../../../../examples/guide/bst_map_type_invariant.rs:all}}
17 | ```
18 |
19 | ## Version with generic key type and Clone implementation
20 |
21 | ```rust
22 | {{#include ../../../../examples/guide/bst_map_generic.rs:all}}
23 | ```
24 |
--------------------------------------------------------------------------------
/source/docs/guide/src/datatypes.md:
--------------------------------------------------------------------------------
1 | # Datatypes: Structs and Enums
2 |
3 | Datatypes, in both executable code and specifications, are
4 | defined via Rust's [`struct`](datatypes_struct.md) and [`enum`](datatypes_enum.md).
5 |
--------------------------------------------------------------------------------
/source/docs/guide/src/datatypes_struct.md:
--------------------------------------------------------------------------------
1 | ## Struct
2 |
3 | In Verus, just as in Rust, you can use `struct` to define a datatype that
4 | collects a set of fields together:
5 | ```rust
6 | {{#include ../../../../examples/guide/datatypes.rs:point}}
7 | ```
8 |
9 | Spec and exec code can refer to `struct` fields:
10 | ```rust
11 | {{#include ../../../../examples/guide/datatypes.rs:point-impl}}
12 | ```
13 |
--------------------------------------------------------------------------------
/source/docs/guide/src/develop_proofs.md:
--------------------------------------------------------------------------------
1 | # Developing Proofs
2 |
3 | In this chapter, we present several examples showing useful techniques for developing proofs
4 | about your code in Verus.
5 |
--------------------------------------------------------------------------------
/source/docs/guide/src/exec_termination.md:
--------------------------------------------------------------------------------
1 | # Lightweight termination checking
2 |
3 | While recursive `spec` functions and `proof` functions must always terminate and therefore must always contain a decreases clause, nontermination is allowed for exec functions. Nevertheless, by default, Verus still requires that recursive `exec` functions and loops in `exec` mode have a `decreases` clause. This only guarantees that the present function will terminate, on the assumption that all the callees also terminate so it should be treated as a lint, not a complete guarantee of termination.
4 |
5 | The attribute #![verifier::exec_allows_no_decreases_clause] can be used to disable this check for a function, module, or crate.
--------------------------------------------------------------------------------
/source/docs/guide/src/for.md:
--------------------------------------------------------------------------------
1 | # For Loops
2 |
3 | The previous section introduced a `while` loop implementation of `triangle`:
4 |
5 | ```rust
6 | {{#include ../../../../examples/guide/recursion.rs:loop}}
7 | ```
8 |
9 | We can rewrite this as a `for` loop as follows:
10 |
11 | ```rust
12 | {{#include ../../../../examples/guide/recursion.rs:for_loop}}
13 | ```
14 |
15 | The only difference between this `for` loop and the `while` loop
16 | is that `idx` is automatically incremented by 1 at the end of the
17 | each iteration.
18 |
19 | In addition, `iter.start`, `iter.cur`, `iter.end` reveal the start, current, and end
20 | for the iterator of range `0..n`.
21 | `iter@` records all the elements that the iterator has iterated so far.
22 | In the above example, if `idx=3`, `iter@ =~= seq![0,1,2]`
23 |
--------------------------------------------------------------------------------
/source/docs/guide/src/getting_started.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | In this chapter, we'll walk you through setting up Verus and running it on a sample program.
4 | You can either:
5 |
6 | * [Install Verus and run it from the command line](./getting_started_cmd_line.md)
7 | * [Install Verus and run it from within VSCode](./getting_started_vscode.md)
8 |
9 | If you don't want to install Verus yet, but just want to experiment with it or follow
10 | along the tutorial, you can also run Verus through [the Verus playground](https://play.verus-lang.org/) in your browser.
11 |
--------------------------------------------------------------------------------
/source/docs/guide/src/graphics/verus-analyzer-error-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/guide/src/graphics/verus-analyzer-error-example.png
--------------------------------------------------------------------------------
/source/docs/guide/src/graphics/verusdoc-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/guide/src/graphics/verusdoc-example.png
--------------------------------------------------------------------------------
/source/docs/guide/src/guarantees.md:
--------------------------------------------------------------------------------
1 | # Understanding the guarantees of a verified program
2 |
3 | A persistent challenge with verified software is understanding what, exactly, is being verified and what guarantees are being given. Verified code doesn't run in a vacuum; verified code ofter interacts with unverified code, possibly in either direction. This chapter documents technical information need to properly understand how verified code might interact with unverified code.
4 |
--------------------------------------------------------------------------------
/source/docs/guide/src/higher-order-fns.md:
--------------------------------------------------------------------------------
1 | # Higher-order executable functions
2 |
3 | Here we discuss the use of higher order functions via closures and other function types in Rust.
4 |
--------------------------------------------------------------------------------
/source/docs/guide/src/interacting-with-unverified-code.md:
--------------------------------------------------------------------------------
1 | # Interacting with unverified code
2 |
3 | We typically only verify a portion of a Rust code base. This chapter discusses
4 | how to [call unverified code from verified
5 | code](./calling-unverified-from-verified.md), as well as some caveats and
6 | strategies for safely allowing [unverified code to call verified
7 | code](./calling-verified-from-unverified.md)
8 |
--------------------------------------------------------------------------------
/source/docs/guide/src/performance.md:
--------------------------------------------------------------------------------
1 | # Meausuring verification performance
2 |
3 | To see a more detailed breakdown of where Verus is spending time, you can pass
4 | `--time` on the command line. For even more details, try `--time-expanded`.
5 | For a machine-readable output, add `--output-json`. These flags will also
6 | report on the SMT resources (rlimit) used. SMT resources are an advanced topic;
7 | they give a *very rough* estimate of how hard the SMT solver worked on the provided
8 | query (or queries).
9 |
10 | See `verus --help` for more information about these options.
11 |
--------------------------------------------------------------------------------
/source/docs/guide/src/pointers.md:
--------------------------------------------------------------------------------
1 | {{#include ./reference-pointers-cells.md}}
2 |
--------------------------------------------------------------------------------
/source/docs/guide/src/prefix-and-or.md:
--------------------------------------------------------------------------------
1 | # Prefix and/or (`&&&` and `|||`)
2 |
3 | The prefix and/or operators (`&&&` and `|||`) are explained in [Expressions and operators for specifications](operators.md).
4 |
--------------------------------------------------------------------------------
/source/docs/guide/src/recursion_loops.md:
--------------------------------------------------------------------------------
1 | # Recursion and loops
2 |
3 | Suppose we want to compute the nth
4 | [triangular number](https://en.wikipedia.org/wiki/Triangular_number):
5 |
6 | ```
7 | triangle(n) = 0 + 1 + 2 + ... + (n - 1) + n
8 | ```
9 |
10 | We can express this as a simple recursive funciton:
11 |
12 | ```rust
13 | {{#include ../../../../examples/guide/recursion.rs:spec}}
14 | ```
15 |
16 | This chapter discusses how to define and use recursive functions,
17 | including writing `decreases` clauses and using fuel.
18 | It then explores a series of verified implementations of `triangle`,
19 | starting with a basic recursive implementation and ending with a while loop.
20 |
--------------------------------------------------------------------------------
/source/docs/guide/src/ref-extensional-equality.md:
--------------------------------------------------------------------------------
1 | # Extensional equality (`=~=` and `=~~=`)
2 |
3 | The extensional equality operators `=~=` and `=~~=` are explained in
4 | [Extensional equality](extensional_equality.md).
5 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-assert-by-nonlinear.md:
--------------------------------------------------------------------------------
1 | # assert ... by(nonlinear_arith)
2 |
3 | Invoke Z3's nonlinear solver to prove the given predicate.
4 |
5 | ```
6 | assert(P) by(bit_vector);
7 | ```
8 |
9 | ```
10 | assert(P) by(bit_vector)
11 | requires Q;
12 | ```
13 |
14 | The solver uses Z3's theory of nonlinear arithmetic. This can often solve problems
15 | that involve multiplication or division of symbolic values. For example,
16 | commutativity axioms like `a * b == b * a` are accessible in this mode.
17 |
18 | The prover does not have access to any prior context except that which is given in
19 | the `requires` clause, if provided. If the `requires` clause is provided, then the
20 | bit vector solver attempts to prove `Q ==> P`. Verus will also check (using its normal solver)
21 | that `Q` holds from the prior proof context.
22 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-assert-by.md:
--------------------------------------------------------------------------------
1 | # assert ... by
2 |
3 | The `assert ... by` statement is used to encapsulate a proof. For a boolean `spec` expression, `P`, one writes:
4 |
5 | ```rust
6 | assert(P) by {
7 | // ... proof here
8 | }
9 | // ... remainder
10 | ```
11 |
12 | Verus will validate the proof and then attempt to use it to prove the P.
13 | The contents of the proof, however, will not be included in the context used to
14 | prove the remainder.
15 | Only `P` will be introduced into the context for the remainder.
16 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-assert-forall-by.md:
--------------------------------------------------------------------------------
1 | # assert forall ... by
2 |
3 | The `assert forall ... by` statement is used to write a proof of a `forall` expression
4 | while introducing the quantified variables into the context.
5 |
6 | ```rust
7 | assert forall |idents| P by {
8 | // ... proof here
9 | }
10 | // ... remainder
11 | ```
12 |
13 | Much like an ordinary [`assert ... by`](./reference-assert-by.md) statement, the proof
14 | inside the body does not enter the context for the remainder of the proof.
15 | Only the `forall |idents| P` expression enters the context.
16 | Furthermore, within the proof body, the variables in the `idents` may be
17 |
18 | Note that the **parentheses _must_ be left off**, in contrast to other kinds of `assert` statements.
19 |
20 | For convenience, you can use `implies` to introduce a hypothesis automatically into
21 | the proof block:
22 |
23 | ```rust
24 | assert forall |idents| H implies P by {
25 | // ... proof here
26 | }
27 | // ... remainder
28 | ```
29 |
30 | This will make `H` available in the proof block, so you only have to prove `P`.
31 | In the end, the predicate `forall |idents| H ==> P` will be proved.
32 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-at-sign.md:
--------------------------------------------------------------------------------
1 | # The view function `@`
2 |
3 | The expression `expr@` is a shorthand for `expr.view()`. The `view()` function is a Verus
4 | convention for the abstraction of an exec-mode object, usually [defined by the `View` trait](https://verus-lang.github.io/verus/verusdoc/vstd/view/trait.View.html).
5 | However, the expansion of the `@` syntax is purely syntactic, so it does not necessarily
6 | correspond to the trait function.
7 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-chained-op.md:
--------------------------------------------------------------------------------
1 | # Chained operators
2 |
3 | In spec code, equality and inequality operators can be chained. For example,
4 | `a <= b < c`
5 | is equivalent to
6 | `a <= b && b < c`.
7 |
8 | Chained inequalities support `<`, `<=`, `>`, `>=`, and `==`, and support sequences of chained
9 | operators of arbitrary length.
10 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-flag-record.md:
--------------------------------------------------------------------------------
1 | # Record flag
2 |
3 | Sometimes, you might wish to record an execution trace of Verus to share, along with all the necessary dependencies to reproduce an execution.
4 | This might be useful for either packaging up your verified project, or to report a Verus bug to the [issue tracker](https://github.com/verus-lang/verus/issues).
5 |
6 | The `--record` flag will do precisely this. In particular, to record an execution of Verus (say, `verus foo --bar --baz`), simply add the `--record` flag (for example, `verus foo --bar --baz --record`). This will re-run Verus, and package all the relevant source files, along with the execution output and version information into a zip file (`yyyy-mm-dd-hh-mm-ss.zip`) in your current directory.
7 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-implication.md:
--------------------------------------------------------------------------------
1 | # Implication (==>, <==, and <==>)
2 |
3 | The operator `P ==> Q`, read _P implies Q_, is equivalent to `!P || Q`.
4 |
5 | This can also be written backwards: `Q <== P` is equivalent to `P ==> Q`.
6 |
7 | Finally, `P <==> Q` is equivalent to `P == Q`. It is sometimes useful for readability,
8 | and because `<==>` has the same syntactic precedence as `==>`
9 | rather than the precedence of `==`.
10 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-opens-invariants.md:
--------------------------------------------------------------------------------
1 | # opens_invariants
2 |
3 | The `opens_invariants` clause may be applied to any `proof` or `exec` function.
4 |
5 | This indicates the set of _names_ of tracked invariants that may be opened by the function.
6 | At this time, it has three forms. See [the documentation for `open_local_invariant`](https://verus-lang.github.io/verus/verusdoc/vstd/macro.open_local_invariant.html#avoiding-reentrancy) for more information about why Verus enforces these restrictions.
7 |
8 | ```
9 | fn example()
10 | opens_invariants any
11 | {
12 | // Any invariant may be opened here
13 | }
14 | ```
15 |
16 | or:
17 |
18 | ```
19 | fn example()
20 | opens_invariants none
21 | {
22 | // No invariant may be opened here
23 | }
24 | ```
25 |
26 | or:
27 |
28 | ```
29 | fn example()
30 | opens_invariants [ $EXPR1, $EXPR2, ... ]
31 | {
32 | // Only invariants with names in [ $EXPR1, $EXPR2, ... ] may be opened.
33 | }
34 | ```
35 |
36 | ### Defaults
37 |
38 | For `exec` functions, the default is `opens_invariants any`.
39 |
40 | For `proof` functions, the default is `opens_invariants none`.
41 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-pointers-cells.md:
--------------------------------------------------------------------------------
1 | # Pointers and cells
2 |
3 | See the vstd documentation for more information on handling these features.
4 |
5 | - For cells, see [`PCell`](https://verus-lang.github.io/verus/verusdoc/vstd/cell/struct.PCell.html)
6 | - For pointers to fixed-sized heap allocations, see [`PPtr`](https://verus-lang.github.io/verus/verusdoc/vstd/simple_pptr/struct.PPtr.html).
7 | - For general support for `*mut T` and `*const T`, see [`vstd::raw_ptr`](https://verus-lang.github.io/verus/verusdoc/vstd/raw_ptr/index.html)
8 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-recommends.md:
--------------------------------------------------------------------------------
1 | # recommends
2 |
3 | See [this guide page](./spec_vs_proof.md#recommends) for motivation and overview.
4 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-returns.md:
--------------------------------------------------------------------------------
1 | # returns
2 |
3 | The `returns` clause is syntactic sugar for an `ensures` clause of a certain form.
4 | The `returns` clause can be provided instead of or in addition to an `ensures` clause.
5 |
6 | The following:
7 |
8 | ```rust
9 | fn example() -> return_type
10 | returns $expr
11 | {
12 | ...
13 | }
14 | ```
15 |
16 | is equivalent to:
17 |
18 | ```rust
19 | fn example() -> (return_name: return_type)
20 | ensures return_name == $expr
21 | {
22 | ...
23 | }
24 | ```
25 |
26 | ## With the `#![verifier::allow_in_spec]` attribute
27 |
28 | The [`#![verifier::allow_in_spec]` attribute](./reference-attributes.md#verifierallowinspec) attribute can be applied to an executable function with a [`returns` clause](./reference-returns.md). This allows the function to be used in spec mode, where it is interpreted as equivalent to the specified return-value.
29 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-reveal-hide.md:
--------------------------------------------------------------------------------
1 | # `reveal`, `reveal_with_fuel`, `hide`
2 |
3 | These attributes control whether and how Verus will unfold the definition of a spec function
4 | while solving. For a spec function `f`:
5 |
6 | - `reveal(f)` directs Verus to unfold the definition of `f` when it encounters a use of `f`.
7 | - `hide(f)` directs Verus to treat `f` as an uninterpreted function without reasoning
8 | about its definition.
9 |
10 | Technically speaking, Verus handles "function unfolding" by
11 | creating axioms of the form `forall |x| f(x) == (definition of f(x))`.
12 | Thus, `reveal(f)` makes this axiom accessible to the solver,
13 | while `hide(f)` makes this axiom inaccessible.
14 |
15 | By default, functions are always revealed when they are in scope. This can be changed
16 | by marking the function with the `#[verifier::opaque]` attribute.
17 |
18 | The `reveal_with_fuel(f, n)` directive is used for recursive functions.
19 | The integer `n` indicates how many times Verus should unfold a recursive function.
20 | Limiting the fuel to a finite amount is necessary to avoid
21 | [trigger loops](multitriggers.md#matching-loops-what-they-are-and-to-avoid-them).
22 | The default fuel (absent any `reveal_with_fuel` directive) is 1.
23 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-signature-inheritance.md:
--------------------------------------------------------------------------------
1 | # Signature inheritance
2 |
3 | Usually, the developer does not write a signature for methods in a trait implementation,
4 | as the signatures are inherited from the trait declaration. However, the signature can
5 | be modified in limited ways. To ensure soundness of the trait system, Verus has to make
6 | sure that the signature on any function must be at least as strong as the
7 | corresponding signature on the trait declaration.
8 |
9 | * All `requires` clauses in a trait declaration are inherited in the trait implementation.
10 | The user cannot
11 | add additional `requires` clauses in a trait implementation.
12 | * All `ensures` clauses in a trait declaration are inherited in the trait implementation.
13 | Furthermore, the user can add additional `ensures` clauses in the trait implementation.
14 | * The [`opens_invariants` signature](./reference-opens-invariants.md) is inherited
15 | in the trait implementation and cannot be modified.
16 | * The [unwinding signature](./reference-unwind-sig.md) is inherited
17 | in the trait implementation and cannot be modified.
18 |
19 | When a trait function is called, Verus will attempt to statically resolve the function
20 | to a particular trait implementation. If this is possible, it uses the possibly-stronger
21 | specification from the trait implementation; in all other cases, it uses the
22 | generic specification from the trait declaration.
23 |
--------------------------------------------------------------------------------
/source/docs/guide/src/reference-spec-index.md:
--------------------------------------------------------------------------------
1 | # Spec index operator []
2 |
3 | In spec expressions, the index operator is treated differently than
4 | in exec expressions, where it corresponds to the [usual Rust index operator](https://doc.rust-lang.org/std/ops/trait.Index.html).
5 |
6 | Specifically, in a spec expression, the expression `expr[i]` is a shorthand for
7 | `expr.spec_index(i)`. This is a purely syntactic transformation, and there is no
8 | particular trait.
9 |
10 | For example:
11 |
12 | * [`spec_index` for a Seq](https://verus-lang.github.io/verus/verusdoc/vstd/seq/struct.Seq.html#method.spec_index)
13 | * [`spec_index` for a Map](https://verus-lang.github.io/verus/verusdoc/vstd/map/struct.Map.html#method.spec_index)
14 | * [`spec_index` for a slice](https://verus-lang.github.io/verus/verusdoc/vstd/slice/trait.SliceAdditionalSpecFns.html#tymethod.spec_index)
15 |
--------------------------------------------------------------------------------
/source/docs/guide/src/smt_perf_overview.md:
--------------------------------------------------------------------------------
1 | # Managing proof performance and why it's critical
2 |
3 | Sometimes your proof succeeds, but it takes too long. It's tempting to simply
4 | tolerate the longer verification time and move on. However, we urge you to
5 | take the time to improve the verification performance. Slow verification
6 | performance typically has an underlying cause. Diagnosing and fixing the cause
7 | is much easier to do as the problems arise; waiting until you have multiple
8 | performance problems compounds the challenges of diagnosis and repair. Plus,
9 | if the proof later breaks, you'll appreciate having a short code-prove
10 | development cycle. Keeping verification times short also makes it easier to
11 | check for regressions.
12 |
13 | This chapter describes various ways to measure the performance of your
14 | proofs and steps you can take to improve it.
15 |
--------------------------------------------------------------------------------
/source/docs/guide/src/spec-choose.md:
--------------------------------------------------------------------------------
1 | # Such that (`choose`)
2 |
3 | The such-that operator (`choose`) is explained in [exists and choose](exists.md).
4 |
--------------------------------------------------------------------------------
/source/docs/guide/src/spec-equality.md:
--------------------------------------------------------------------------------
1 | # Spec equality (`==`)
2 |
3 | The spec equality operator `==` is explained in [Equality](./equality.md).
4 |
--------------------------------------------------------------------------------
/source/docs/guide/src/spec-expressions.md:
--------------------------------------------------------------------------------
1 | # Spec expressions
2 |
3 | Many built-in operators are in spec mode, i.e., they can be used in
4 | specification expressions. This section discusses those operators.
5 |
--------------------------------------------------------------------------------
/source/docs/guide/src/spec-quantifiers.md:
--------------------------------------------------------------------------------
1 | # Spec quantifiers (`forall`, `exists`)
2 |
3 | Quantifiers are explained in the [Quantifiers](quants.md) part of the
4 | tutorial. Specifically, `forall` is explained in [forall and
5 | triggers](forall.md) and `exists` is explained in [exists and
6 | choose](exists.md).
7 |
--------------------------------------------------------------------------------
/source/docs/guide/src/spec_closures.md:
--------------------------------------------------------------------------------
1 | # Spec Closures
2 |
3 | Verus supports anonymous functions (known as "closures" in Rust) in ghost code.
4 | For example, the following code from earlier in [this chapter](spec_lib.md)
5 | uses an anonymous function `|i: int| 10 * i`
6 | to initialize a sequence with the values 0, 10, 20, 30, 40:
7 |
8 | ```rust
9 | {{#include ../../../../examples/guide/lib_examples.rs:new0}}
10 | ```
11 |
12 | The anonymous function `|i: int| 10 * i` has type `spec_fn(int) -> int`
13 | and has mode `spec`.
14 | Because it has mode `spec`,
15 | the anonymous function is subject to the [same restrictions](modes.md) as named `spec` functions.
16 | (For example, it can call other `spec` functions but not `proof` functions or `exec` functions.)
17 |
18 | Note that in contrast to standard executable
19 | [Rust closures](https://doc.rust-lang.org/book/ch13-01-closures.html),
20 | where `Fn`, `FnOnce`, and `FnMut` are traits,
21 | `spec_fn(int) -> int` is a type, not a trait.
22 | Therefore, ghost code can return a spec closure directly,
23 | using a return value of type `spec_fn(t1, ..., tn) -> tret`,
24 | without having to use
25 | [dyn or impl](https://doc.rust-lang.org/book/ch19-05-advanced-functions-and-closures.html#returning-closures),
26 | as with standard executable Rust closures.
27 | For example, the `spec` function `adder`, shown below,
28 | can return an anonymous function that adds `x` to `y`:
29 |
30 | ```rust
31 | {{#include ../../../../examples/guide/lib_examples.rs:ret_spec_fn}}
32 | ```
33 |
--------------------------------------------------------------------------------
/source/docs/guide/src/specs.md:
--------------------------------------------------------------------------------
1 | # Basic specifications
2 |
3 | Verus programs contain *specifications* to describe the
4 | intended behavior of the code.
5 | These specifications include preconditions, postconditions, assertions, and loop invariants.
6 | Specifications are one form of *ghost code* --- code that appears in the Rust source code for verification's sake,
7 | but does not appear in the compiled executable.
8 |
9 | This chapter will walk through some basic examples of preconditions, postconditions,
10 | and assertions, showing the syntax for writing these specifications
11 | and discussing integer arithmetic and equality in specifications.
12 |
--------------------------------------------------------------------------------
/source/docs/guide/src/static.md:
--------------------------------------------------------------------------------
1 | # Static items
2 |
3 | Verus supports static items, similar to `const` items. Unlike `const` items, though,
4 | `static` items are only usable in `exec` mode. Note that this requires them to be
5 | _explicitly_ marked as `exec`:
6 |
7 | ```
8 | exec static x: u64 = 0;
9 | ```
10 |
11 | The reason for this is consistency with `const`; for `const` items, the default mode
12 | for an unmarked const item is the [dual `spec`-`exec` mode](./const.md).
13 | However, this mode is not supported for `static` items; therefore, static items
14 | need to be explicitly marked `exec`.
15 |
16 | Note there are some **limitations** to the current support for `static` items.
17 | Currently, a static item cannot be referenced from a spec expression. This means, for example,
18 | that you can't prove that two uses of the same static item give the same value
19 | if those uses are in different functions. We expect this limitation will be lifted
20 | in the future.
21 |
--------------------------------------------------------------------------------
/source/docs/guide/src/syntax.md:
--------------------------------------------------------------------------------
1 | # Verus Syntax
2 |
3 | The code below illustrates a large swath of Verus' syntax.
4 |
5 | ```rust
6 | {{#include ../../../../examples/syntax.rs}}
7 | ```
8 |
--------------------------------------------------------------------------------
/source/docs/guide/src/vstd.md:
--------------------------------------------------------------------------------
1 | # Libraries
2 |
3 | The Verus standard library, `vstd`, comes with a variety of utilities and
4 | datatypes for proofs, as well as runtime functionality with specifications.
5 | Most Verus programs will start with `use vstd::prelude::*;`, which pulls
6 | in a default set of definitions that we find generally useful. This chapter
7 | will introduce a few of them, but you can find more complete descriptions
8 | in the [vstd documentation](https://verus-lang.github.io/verus/verusdoc/vstd/).
9 |
--------------------------------------------------------------------------------
/source/docs/internal/record-history.md:
--------------------------------------------------------------------------------
1 | The `record-history` feature records every invocation of Verus with the current source of the crate it was invoked on, and the Verus verification results and outputs.
2 |
3 | To enable, re-build vargo, then compile Verus with `--features record-history`:
4 |
5 | ```
6 | vargo build --release --features record-history
7 | ```
8 |
9 | Then you need a per-project opt-in.
10 | To opt-in place an empty directory named `.record-history` in the same directory as the file that acts as the crate root. That is, if you normally run Verus as
11 |
12 | ```
13 | verus path/to/foo.rs
14 | ```
15 |
16 | Add an empty folder named `path/to/.record-history`.
17 |
18 | The next time Verus is run, it will create `path/to/.record-history/git`, which will contain a bare repo with the recordings.
--------------------------------------------------------------------------------
/source/docs/internal/wiki-archive/Home.md:
--------------------------------------------------------------------------------
1 | ## Design and project goals: [[Goals]]
2 |
3 | ## Status
4 |
5 | [[Status: currently supported Rust features]]
6 |
--------------------------------------------------------------------------------
/source/docs/internal/wiki-archive/README.md:
--------------------------------------------------------------------------------
1 | This is an archive of the outdated files from the Wiki.
2 |
3 | This content is either out-of-date or has been moved elsewhere.
4 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/.gitignore:
--------------------------------------------------------------------------------
1 | _site/
2 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/Makefile:
--------------------------------------------------------------------------------
1 | all: build
2 | jekyll serve
3 |
4 | build:
5 | jekyll build
6 |
7 | clean:
8 | rm -rf _site/
9 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_config.yml:
--------------------------------------------------------------------------------
1 | title: "Verus — Publications and Projects"
2 | lsi: false
3 | safe: true
4 | source: .
5 | incremental: false
6 | highlighter: rouge
7 | collections:
8 | - projects
9 | gist:
10 | noscript: false
11 | kramdown:
12 | math_engine: mathjax
13 | syntax_highlighter: rouge
14 | exclude: [Makefile]
15 | pubtypes: ["internal", "external"]
16 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Verus — Projects
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{ content }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/alpha-verus.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "AlphaVerus: Bootstrapping Formally Verified Code Generation through Self-Improving Translation and Treefinement"
3 | authors: "Pranjal Aggarwal, Bryan Parno, Sean Welleck"
4 | venue: "Proceedings of the International Conference on Machine Learning (ICML)"
5 | date: 2025-07-14
6 | type: external
7 | pdf: https://arxiv.org/pdf/2412.06176
8 | code: https://github.com/cmu-l3/alphaverus
9 |
10 | ---
11 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/anvil.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Anvil: Verifying Liveness of Cluster Management Controllers"
3 | authors: "Xudong Sun, Wenjie Ma, Jiawei Tyler Gu, Zicheng Ma, Tej Chajed, Jon Howell, Andrea Lattuada, Oded Padon, Lalith Suresh, Adriana Szekeres, Tianyin Xu"
4 | venue: "Proceedings of the USENIX Symposium on Operating Systems Design and Implementation (OSDI)"
5 | date: 2024-07-11
6 | type: external
7 | pdf: https://www.usenix.org/conference/osdi24/presentation/sun-xudong
8 | code: https://github.com/vmware-research/verifiable-controllers
9 | award: Best Paper Award
10 | ---
11 |
12 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/atmosphere.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Atmosphere: Towards Practical Verified Kernels in Rust"
3 | authors: "Xiangdong Chen, Zhaofeng Li, Lukas Mesicek, Vikram Narayanan, Anton Burtsev"
4 | venue: "Proceedings of the Workshop on Kernel Isolation, Safety and Verification (KISV)"
5 | date: 2023-10-23
6 | type: external
7 | pdf: https://doi.org/10.1145/3625275.3625401
8 | ---
9 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/auto-verus.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "AutoVerus: Automated Proof Generation for Rust Code"
3 | authors: "Chenyuan Yang, Xuheng Li, Md Rakib Hossain Misu, Jianan Yao, Weidong Cui, Yeyun Gong, Chris Hawblitzel, Shuvendu Lahiri, Jacob R. Lorch, Shuai Lu, Fan Yang, Ziqiao Zhou, and Shan Lu"
4 | venue: "arXiv"
5 | date: 2024-09-19
6 | type: external
7 | pdf: https://arxiv.org/pdf/2409.13082
8 | code: https://github.com/microsoft/verus-proof-synthesis
9 |
10 | ---
11 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/beyond-isolation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Beyond Isolation: OS Verification as a Foundation for Correct Applications,"
3 | authors: "Matthias Brun, Reto Achermann, Tej Chajed, Jon Howell, Gerd Zellweger, Andrea Lattuada"
4 | venue: "Proceedings of the Workshop on Hot Topics in Operating Systems (HotOS)"
5 | date: 2023-06-22
6 | type: external
7 | pdf: https://andrea.lattuada.me/assets/hotos23-beyond-isolation.pdf
8 | ---
9 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/ghost-linear.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Verus: Verifying Rust Programs using Linear Ghost Types"
3 | authors: "Andrea Lattuada, Travis Hance, Chanhee Cho, Matthias Brun, Isitha Subasinghe, Yi Zhou, Jon Howell, Bryan Parno, Chris Hawblitzel"
4 | venue: "Proceedings of the ACM Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA)"
5 | date: 2023-12-01
6 | type: internal
7 | category: "Language and Verification"
8 | pdf: https://www.andrew.cmu.edu/user/bparno/papers/verus-ghost.pdf
9 | code: https://github.com/verus-lang/verus
10 |
11 | ---
12 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/hance-thesis.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Verifying Concurrent Systems Code"
3 | authors: "Travis Hance"
4 | venue: "PhD Thesis, Carnegie Mellon University"
5 | date: 2024-08-07
6 | type: internal
7 | category: "Language and Verification"
8 | pdf: https://www.andrew.cmu.edu/user/bparno/papers/hance_thesis.pdf
9 | award: Honorable Mention for the CMU School of Computer Science Dissertation Award
10 |
11 | ---
12 |
13 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/ironfleet-kv.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "A Distributed Key-Value Store"
3 | date: 2024-05-01
4 | type: project
5 | code: https://github.com/verus-lang/verified-ironkv
6 | ---
7 |
8 | A port of the IronKV system from [IronFleet](https://github.com/microsoft/Ironclad/tree/main/ironfleet) to Verus. IronKV uses distribution for improved throughput by moving "hot" keys to dedicated machines.
9 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/leaf.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Leaf: Modularity for Temporary Sharing in Separation Logic"
3 | authors: "Travis Hance, Jon Howell, Oded Padon, and Bryan Parno"
4 | venue: "Proceedings of the ACM Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA)"
5 | date: 2023-12-01
6 | type: internal
7 | category: "Language and Verification"
8 | pdf: https://www.andrew.cmu.edu/user/bparno/papers/leaf.pdf
9 | code: https://github.com/secure-foundations/leaf
10 | ---
11 |
12 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/llm-mainstream.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Can LLMs Enable Verification in Mainstream Programming?"
3 | authors: "Aleksandr Shefer, Igor Engel, Stanislav Alekseev, Daniil Berezun, Ekaterina Verbitskaia, and Anton Podkopaev"
4 | venue: "arXiv"
5 | date: 2025-03-18
6 | type: external
7 | pdf: https://arxiv.org/pdf/2503.14183
8 |
9 | ---
10 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/mimalloc.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "A Concurrent Memory Allocator"
3 | date: 2024-05-01
4 | type: project
5 | code: https://github.com/verus-lang/verified-memory-allocator
6 | ---
7 | A memory allocator based on [mimalloc](https://github.com/microsoft/mimalloc).
8 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/nr.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "A Node Replication (NR) Library"
3 | date: 2024-05-01
4 | type: project
5 | code: https://github.com/verus-lang/verified-node-replication
6 | ---
7 | Creates a linearizable NUMA-aware concurrent data structure from a black-box sequential one
8 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/persistent-storage.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "An Append-only Log on Persistent Memory"
3 | date: 2024-05-01
4 | type: project
5 | code: https://github.com/microsoft/verified-storage.git
6 | ---
7 | The implementation handles crash consistency, ensuring that even if the process or machine crashes, it acts like an append-only log across the crashes. It also handles bit corruption, detecting if metadata read from persistent memory is corrupted.
8 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/practical-foundation.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Verus: A Practical Foundation for Systems Verification"
3 | authors: "Andrea Lattuada, Travis Hance, Jay Bosamiya, Matthias Brun, Chanhee Cho, Hayley LeBlanc, Pranav Srinivasan, Reto Achermann, Tej Chajed, Chris Hawblitzel, Jon Howell, Jay Lorch, Oded Padon, and Bryan Parno"
4 | venue: "Proceedings of the ACM Symposium on Operating Systems Principles (SOSP)"
5 | date: 2024-11-05
6 | type: internal
7 | category: "Language and Verification"
8 | pdf: https://www.andrew.cmu.edu/user/bparno/papers/verus-sys.pdf
9 | code: https://verus-lang.github.io/paper-sosp24-artifact/
10 | award: Distinguished Artifact Award
11 |
12 | ---
13 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/proof-plumber.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "A Framework for Debugging Automated Program Verification Proofs via Proof Actions"
3 | authors: "Chanhee Cho, Yi Zhou, Jay Bosamiya, and Bryan Parno"
4 | venue: "Proceedings of the Conference on Computer Aided Verification (CAV)"
5 | date: 2024-07-01
6 | type: internal
7 | category: "Tooling"
8 | pdf: https://www.andrew.cmu.edu/user/bparno/papers/proof-plumber.pdf
9 | code: https://github.com/verus-lang/verus-analyzer
10 | award: Distinguished Paper Award
11 | ---
12 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/rag-verus.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "RAG-Verus: Repository-Level Program Verification with LLMs using Retrieval Augmented Generation"
3 | authors: "Sicheng Zhong, Jiading Zhu, Yifang Tian, and Xujie Si"
4 | venue: "arXiv"
5 | date: 2025-02-07
6 | type: external
7 | pdf: https://arxiv.org/pdf/2502.05344
8 |
9 | ---
10 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/safe-verus.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Automated Proof Generation for Rust Code via Self-Evolution"
3 | authors: "Tianyu Chen, Shuai Lu, Shan Lu, Yeyun Gong, Chenyuan Yang, Xuheng Li, Md Rakib Hossain Misu, Hao Yu, Nan Duan, Peng Cheng, Fan Yang, Shuvendu K Lahiri, Tao Xie, and Lidong Zhou"
4 | venue: "Proceedings of the International Conference on Learning Representations (ICLR)"
5 | date: 2025-04-24
6 | type: external
7 | pdf: https://arxiv.org/pdf/2410.15756
8 |
9 | ---
10 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/verified-ostd.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Asterinas OSTD (Operating System Standard Library)"
3 | date: 2025-06-03
4 | type: project
5 | code: https://github.com/asterinas/vostd
6 | ---
7 |
8 | The `vostd` project provides a formally-verified version of OSTD, the (unofficial) standard library for OS development in safe Rust.
9 |
10 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/verified-pagetable.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "An OS Page Table Management Implementation and OS Model"
3 | date: 2024-08-15
4 | type: project
5 | code: https://github.com/utaal/verified-nrkernel
6 | ---
7 |
8 | A verified implementation of an OS' page table management code, and proofs that it behaves according to a userspace process' expectations when combined with a model of the hardware's memory management (memory translation) subsystem.
9 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/verismo.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "VeriSMo: A Verified Security Module for Confidential VMs"
3 | authors: "Ziqiao Zhou, Anjali, Weiteng Chen, Sishuai Gong, Chris Hawblitzel, Weidong Cui"
4 | venue: "Proceedings of the USENIX Symposium on Operating Systems Design and Implementation (OSDI)"
5 | date: 2024-07-11
6 | type: external
7 | pdf: https://www.usenix.org/conference/osdi24/presentation/zhou
8 | code: https://github.com/microsoft/verismo
9 | award: Best Paper Award
10 | ---
11 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/_projects/vest.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Vest: Verified Parsers and Serializers"
3 | date: 2024-09-01
4 | type: project
5 | code: https://github.com/secure-foundations/vest
6 | ---
7 | High-assurance and performant parsing and serialization of binary data formats.
8 |
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/award.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/publications-and-projects/award.jpg
--------------------------------------------------------------------------------
/source/docs/publications-and-projects/css/base.css:
--------------------------------------------------------------------------------
1 | * { margin: 0; padding: 0;}
2 |
3 | body, html { height:100%; }
4 | body {
5 | padding-top: 20px;
6 | font-family: 'Open Sans', sans-serif;
7 | font-size: 11pt;
8 | }
9 | a {
10 | text-decoration: none;
11 | }
12 | a:hover {
13 | text-decoration: underline;
14 | }
15 |
16 | div.main {
17 | display: block;
18 | background-color: white;
19 | padding: 30px 10px 30px 10px;
20 | color: #222;
21 | border-bottom: 1px solid #999;
22 | }
23 | div.posts {
24 | display: block;
25 | flex-grow: 1;
26 | margin-left: 30px;
27 | margin-right: 30px;
28 | max-width: 500px;
29 | }
30 | div.posts .excerpt {
31 | text-align: justify;
32 | }
33 | div.main:first-child {
34 | margin-top: 20px;
35 | border-top: 1px solid #999;
36 | }
37 | div.main:last-child {
38 | margin-bottom: 40px;
39 | }
40 | div.main.highlight {
41 | background-color: #d0d0ff;
42 | }
43 |
44 | div.base_header {
45 | display: flex;
46 | justify-content: space-between;
47 | padding-left: 40px;
48 | padding-right: 40px;
49 | }
50 |
--------------------------------------------------------------------------------
/source/docs/state_machines/.gitignore:
--------------------------------------------------------------------------------
1 | book
2 | *.swp
3 |
--------------------------------------------------------------------------------
/source/docs/state_machines/book.toml:
--------------------------------------------------------------------------------
1 | [book]
2 | language = "en"
3 | multilingual = false
4 | src = "src"
5 | title = "Verus Transition Systems"
6 |
7 | [output.html]
8 | curly-quotes = true
9 |
10 | [output.html.playground]
11 | runnable = false
12 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/counting-to-n-again.md:
--------------------------------------------------------------------------------
1 | # Counting to n (again) (TODO)
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/hash-table.md:
--------------------------------------------------------------------------------
1 | # Hash table (TODO)
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/refcount.md:
--------------------------------------------------------------------------------
1 | # Reference-counted memory (TODO)
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/rust-counting-to-2.md:
--------------------------------------------------------------------------------
1 | # Counting to 2, unverified Rust source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/unverified_counting_to_2.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/rust-counting-to-n.md:
--------------------------------------------------------------------------------
1 | # Counting to _n_, unverified Rust source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/unverified_counting_to_n.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/rust-producer-consumer-queue.md:
--------------------------------------------------------------------------------
1 | # Single-Producer, Single-Consumer queue, unverified Rust source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/unverified_fifo.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/rust-rc.md:
--------------------------------------------------------------------------------
1 | # Reference-counted smart pointer, unverified Rust source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/unverified_rc.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/rwlock.md:
--------------------------------------------------------------------------------
1 | # Reader-writer lock (TODO)
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/src-counting-to-2.md:
--------------------------------------------------------------------------------
1 | # Counting to 2, verified source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/counting_to_2.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/src-counting-to-n.md:
--------------------------------------------------------------------------------
1 | # Counting to _n_, verified source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/counting_to_n.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/src-producer-consumer-queue.md:
--------------------------------------------------------------------------------
1 | # Single-Producer, Single-Consumer queue, example source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/fifo.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/examples/src-rc.md:
--------------------------------------------------------------------------------
1 | # Reference-counted smart pointer, verified source
2 |
3 | ```rust,ignore
4 | {{#include ../../../../../examples/state_machines/tutorial/rc.rs:full}}
5 | ```
6 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/graphics/counting-to-n-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/state_machines/src/graphics/counting-to-n-diagram.png
--------------------------------------------------------------------------------
/source/docs/state_machines/src/graphics/fifo-head-tail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/state_machines/src/graphics/fifo-head-tail.png
--------------------------------------------------------------------------------
/source/docs/state_machines/src/graphics/fifo-protocol-perspective.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/state_machines/src/graphics/fifo-protocol-perspective.png
--------------------------------------------------------------------------------
/source/docs/state_machines/src/graphics/rc-ghost-diagram-ghost-only.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/state_machines/src/graphics/rc-ghost-diagram-ghost-only.png
--------------------------------------------------------------------------------
/source/docs/state_machines/src/graphics/rc-ghost-diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/state_machines/src/graphics/rc-ghost-diagram.png
--------------------------------------------------------------------------------
/source/docs/state_machines/src/graphics/strategy-reference-examples.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/state_machines/src/graphics/strategy-reference-examples.png
--------------------------------------------------------------------------------
/source/docs/state_machines/src/high-level-idea.md:
--------------------------------------------------------------------------------
1 | # High-Level Concepts
2 |
3 | The approach we follow for each of the examples follows roughly this high-level recipe:
4 |
5 | 1. Consider the program you want to verify.
6 | 2. Create an "abstraction" of the program as a tokenized state machine.
7 | 3. Verus will automatically produce for you a bunch of ghost "token types" that make up the
8 | tokenized state machine.
9 | 4. Implement a verified program using the token types
10 |
11 | That doesn't sound too bad, but there's a bit of an art to it, especially in step (2).
12 | To build a proper abstraction, one needs to choose an abstraction which is both abstract
13 | enough that it's easy to prove the relevant properties about, but still concrete enough
14 | that it can be properly connected back to the implementation in step (4).
15 | Choosing this abstraction requires one to identify which pieces of state need to be
16 | in the abstraction, as well as which "tokenization strategy" to use---that's a concept
17 | we'll be introducing soon.
18 |
19 | In the upcoming examples, we'll look at a variety of scenarios and the techniques
20 | we can use to tackle them.
21 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/macro-generated-reference.md:
--------------------------------------------------------------------------------
1 | # Macro-generated code
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/macro-high-level-reference.md:
--------------------------------------------------------------------------------
1 | # State Machine Macro Syntax (TODO)
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/operations.md:
--------------------------------------------------------------------------------
1 | # Operations
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/refinements-reference.md:
--------------------------------------------------------------------------------
1 | # State Machine Refinements
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/state-machine-reference.md:
--------------------------------------------------------------------------------
1 | # State Machine Basics
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/strategy-not-tokenized.md:
--------------------------------------------------------------------------------
1 | # not_tokenized
2 |
3 | The `not_tokenized` strategy can be applied to fields of any type `V`.
4 |
5 | ```rust
6 | fields {
7 | #[sharding(not_tokenized)]
8 | pub field: V,
9 | }
10 | ```
11 |
12 | This results in **no** token types associated to the field `field`.
13 |
14 | It is often useful as a convenient alternative when you would otherwise need an
15 | existential variable in the VerusSync invariant.
16 |
17 | ## Manipulation of the field
18 |
19 | ### Initializing the field
20 |
21 | Initializing the field is done with the usual `init` statement (as it for all strategies).
22 |
23 | ```rust
24 | init field = v;
25 | ```
26 |
27 | Of course, the instance-init function does not emit any tokens for this instruction.
28 |
29 | ### Reading the field
30 |
31 | Reading the field can be done by writing `pre.field`. Notably, this causes the resulting
32 | operation to be non-deterministic in its input arguments. Therefore, `pre.field` can
33 | only be accessed in a [`birds_eye` context](./birds-eye.md).
34 |
35 | ### Updating the field
36 |
37 | The field can always be updated with an `update` statement in any `transition!` operation.
38 |
39 | ```rust
40 | update field = v;
41 | ```
42 |
43 | This does not result in any token inputs or token outputs, and it has no effect on the
44 | signature of the token operation. The `update` instruction may be required in order to
45 | preserve the system invariant.
46 |
47 | ## Example
48 |
49 | TODO
50 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/token-exchanges-as-transitions.md:
--------------------------------------------------------------------------------
1 | # Token exchanges as transitions
2 |
3 | The aim of the framework of tokenized state machines is to marry the power and ergonomics of general transition systems with the token-based approach to concurrency reasoning.
4 |
5 | To make this work, the developer has to do two special things when describing their transitions system:
6 |
7 | * First, they must annotate each field of their state datatype with what we call a _strategy_: the the strategy tells Verus how the state should break down into tokens.
8 | * Second, they must define their transitions using special commands so that the transitions can be interpretted simultaneously as [transitions on the state](./components.md) _and_ as [token exchange functions](./thinking-tokens.md).
9 |
10 | TODO write an explanation for why we need special transitions
11 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/tokenization-reference.md:
--------------------------------------------------------------------------------
1 | # Tokenization
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/tokenized-overview.md:
--------------------------------------------------------------------------------
1 | # Overview (TODO)
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/tokenized.md:
--------------------------------------------------------------------------------
1 | # Tokenized State Machines
2 |
--------------------------------------------------------------------------------
/source/docs/state_machines/src/tutorial-by-example.md:
--------------------------------------------------------------------------------
1 | # Tutorial by example
2 |
3 | In this section, we will walk through a series of increasingly complex examples to illustrate how to use Verus's `tokenized_state_machine!` framework to verify concurrent programs.
4 |
--------------------------------------------------------------------------------
/source/docs/verus-demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/verus-demo.png
--------------------------------------------------------------------------------
/source/docs/verus/.gitignore:
--------------------------------------------------------------------------------
1 | /_site/
2 | /vendor/
3 |
--------------------------------------------------------------------------------
/source/docs/verus/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 | gem 'jekyll'
3 | gem 'kramdown'
4 | gem 'rouge'
5 | gem 'jekyll-feed'
6 | gem 'webrick'
7 |
--------------------------------------------------------------------------------
/source/docs/verus/_config.yml:
--------------------------------------------------------------------------------
1 | title: "Verus"
2 | lsi: false
3 | safe: true
4 | source: .
5 | incremental: false
6 | gist:
7 | noscript: false
8 | exclude: [jekyll-serve-docker.sh]
9 |
--------------------------------------------------------------------------------
/source/docs/verus/_layouts/default.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Verus — Projects
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {{ content }}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/source/docs/verus/assets/verus-color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/verus/assets/verus-color.png
--------------------------------------------------------------------------------
/source/docs/verus/assets/verus-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/verus/assets/verus-gray.png
--------------------------------------------------------------------------------
/source/docs/verus/assets/verus-text-dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
12 |
--------------------------------------------------------------------------------
/source/docs/verus/assets/verus-text-light.svg:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/source/docs/verus/css/base.css:
--------------------------------------------------------------------------------
1 | * { margin: 0; padding: 0;}
2 |
3 | body, html { height:100%; }
4 | body {
5 | padding-top: 20px;
6 | font-family: 'Open Sans', sans-serif;
7 | font-size: 11pt;
8 | }
9 | a {
10 | text-decoration: none;
11 | }
12 | a:hover {
13 | text-decoration: underline;
14 | }
15 |
16 | div.main {
17 | display: block;
18 | background-color: white;
19 | padding: 30px 10px 30px 10px;
20 | color: #222;
21 | border-bottom: 1px solid #999;
22 | }
23 | div.posts {
24 | display: block;
25 | flex-grow: 1;
26 | margin-left: 30px;
27 | margin-right: 30px;
28 | max-width: 500px;
29 | }
30 | div.posts .excerpt {
31 | text-align: justify;
32 | }
33 | div.main:first-child {
34 | margin-top: 20px;
35 | border-top: 1px solid #999;
36 | }
37 | div.main:last-child {
38 | margin-bottom: 40px;
39 | }
40 | div.main.highlight {
41 | background-color: #d0d0ff;
42 | }
43 |
44 | div.base_header {
45 | display: flex;
46 | justify-content: space-between;
47 | padding-left: 40px;
48 | padding-right: 40px;
49 | }
50 |
--------------------------------------------------------------------------------
/source/docs/verus/jekyll-serve-docker.sh:
--------------------------------------------------------------------------------
1 | docker run --rm \
2 | --volume="$PWD:/srv/jekyll:Z" \
3 | --volume="$PWD/vendor/bundle:/usr/local/bundle:Z" \
4 | --publish [::1]:4000:4000 \
5 | jekyll/jekyll \
6 | jekyll serve \
7 | --force_polling
8 |
--------------------------------------------------------------------------------
/source/docs/vscode-demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/docs/vscode-demo.gif
--------------------------------------------------------------------------------
/source/docs/zulip-icon-circle.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/source/lifetime_generate_works.txt:
--------------------------------------------------------------------------------
1 | 42305cc9
2 |
--------------------------------------------------------------------------------
/source/rust_verify/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_verify"
3 | version = "0.1.0"
4 | edition = "2018"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | air = { path = "../air" }
10 | vir = { path = "../vir" }
11 | serde = "1"
12 | serde_json = { version = ">=1.0.95", features = ["preserve_order"] }
13 | bincode = "1.0.1"
14 | sha2 = "0.10.2"
15 | hex = "0.4.3"
16 | sise = "0.6.0"
17 | num-bigint = "0.4.4"
18 | num-format = "0.4.0"
19 | getopts = { git = "https://github.com/utaal/getopts.git", branch = "parse-partial" }
20 | regex = "1"
21 | internals_interface = { path = "../tools/internals_interface" }
22 | indicatif = "0.17.7"
23 | console = { version = "0.15", default-features = false, features = ["ansi-parsing"] }
24 | indexmap = { version = "1" }
25 |
26 | [target.'cfg(windows)'.dependencies]
27 | win32job = "1"
28 |
29 | [dev-dependencies]
30 | rust_verify_test_macros = { path = "../rust_verify_test_macros" }
31 |
32 | [features]
33 | singular = ["vir/singular", "air/singular"]
34 |
35 | [package.metadata.rust-analyzer]
36 | rustc_private = true
37 |
--------------------------------------------------------------------------------
/source/rust_verify/NOTES.md:
--------------------------------------------------------------------------------
1 |
2 | For lang items, consider using
3 | https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/context/struct.TyCtxt.html#method.require_lang_item
4 |
5 | For structural equality, consider
6 | https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyS.html#method.is_structural_eq_shallow
7 | and using a type visitor.
8 |
9 | For field indices, consider
10 | https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.find_field_index
11 |
--------------------------------------------------------------------------------
/source/rust_verify/src/def.rs:
--------------------------------------------------------------------------------
1 | use std::sync::Arc;
2 |
3 | use crate::{context::Context, rust_to_vir_base::def_id_to_vir_path};
4 |
5 | pub const IS_VARIANT_PREFIX: &str = "is";
6 | pub const GET_VARIANT_PREFIX: &str = "get";
7 |
8 | pub(crate) fn path_to_well_known_item(
9 | ctxt: &Context,
10 | ) -> Arc> {
11 | Arc::new(
12 | vec![(
13 | ctxt.tcx.lang_items().drop_trait().expect("drop trait lang item"),
14 | vir::ast::WellKnownItem::DropTrait,
15 | )]
16 | .into_iter()
17 | .map(|(did, wii)| (def_id_to_vir_path(ctxt.tcx, &ctxt.verus_items, did), wii))
18 | .collect(),
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/source/rust_verify/src/file_loader.rs:
--------------------------------------------------------------------------------
1 | pub use rustc_span::source_map::RealFileLoader;
2 |
3 | pub trait FileLoaderClone {
4 | fn clone(&self) -> Self;
5 | }
6 |
7 | impl FileLoaderClone for RealFileLoader {
8 | fn clone(&self) -> Self {
9 | rustc_span::source_map::RealFileLoader
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/source/rust_verify_build_macros/src/bin/build_vstd.rs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/verus-lang/verus/d114f752773b562c4021f17ae35d835e9fe62f59/source/rust_verify_build_macros/src/bin/build_vstd.rs
--------------------------------------------------------------------------------
/source/rust_verify_test/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_verify_test"
3 | version = "0.1.0"
4 | edition = "2018"
5 |
6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7 |
8 | [dependencies]
9 | air = { path = "../air" }
10 | vir = { path = "../vir" }
11 |
12 | [dev-dependencies]
13 | rust_verify_test_macros = { path = "../rust_verify_test_macros" }
14 | regex = "1"
15 | serde = "1"
16 | serde_json = "1"
17 | yansi = "0.5"
18 |
19 | [features]
20 | singular = ["vir/singular", "air/singular"]
21 |
22 | [package.metadata.rust-analyzer]
23 | rustc_private = true
--------------------------------------------------------------------------------
/source/rust_verify_test/tests/erase.rs:
--------------------------------------------------------------------------------
1 | #![feature(rustc_private)]
2 | #[macro_use]
3 | mod common;
4 | use common::*;
5 |
6 | test_verify_one_file! {
7 | #[test] test_regression_78 verus_code! {
8 | use vstd::prelude::*;
9 |
10 | proof fn f1(t: Ghost