├── .git-blame-ignore-revs ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md ├── pull_request_template.md └── workflows │ ├── README │ ├── ci.yml │ ├── get-z3.sh │ ├── pages.yml │ └── release.yml ├── .gitignore ├── .vscode ├── launch.json.template ├── settings.json.template └── tasks.json.template ├── BUILD.md ├── CONTRIBUTING.md ├── INSTALL.md ├── LICENSE ├── README.md ├── dependencies ├── prettyplease │ ├── .gitattributes │ ├── .github │ │ ├── FUNDING.yml │ │ └── workflows │ │ │ └── ci.yml │ ├── .gitignore │ ├── Cargo.toml │ ├── LICENSE-APACHE │ ├── LICENSE-MIT │ ├── README.md │ ├── build.rs │ ├── cargo-expand │ │ ├── anyhow-1.0.58.rs │ │ ├── cargo-tally-1.0.8.rs │ │ ├── cxx-1.0.69.rs │ │ ├── erased-serde-0.3.21.rs │ │ ├── serde-1.0.137.rs │ │ ├── serde_derive-1.0.137.rs │ │ ├── syn-1.0.97.rs │ │ └── update │ │ │ ├── Cargo.toml │ │ │ └── update.rs │ ├── examples │ │ ├── .tokeignore │ │ ├── input.rs │ │ ├── output.prettyplease.rs │ │ ├── output.rustc.rs │ │ ├── output.rustfmt.rs │ │ └── update │ │ │ ├── Cargo.toml │ │ │ └── update-examples.rs │ ├── fuzz │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ └── fuzz_targets │ │ │ └── round_trip.rs │ ├── src │ │ ├── algorithm.rs │ │ ├── attr.rs │ │ ├── classify.rs │ │ ├── convenience.rs │ │ ├── data.rs │ │ ├── expr.rs │ │ ├── file.rs │ │ ├── fixup.rs │ │ ├── generics.rs │ │ ├── item.rs │ │ ├── iter.rs │ │ ├── lib.rs │ │ ├── lifetime.rs │ │ ├── lit.rs │ │ ├── mac.rs │ │ ├── pat.rs │ │ ├── path.rs │ │ ├── precedence.rs │ │ ├── ring.rs │ │ ├── stmt.rs │ │ ├── token.rs │ │ └── ty.rs │ └── tests │ │ ├── test.rs │ │ └── test_precedence.rs └── syn │ ├── .gitattributes │ ├── .github │ ├── FUNDING.yml │ └── workflows │ │ └── ci.yml │ ├── .gitignore │ ├── Cargo.toml │ ├── LICENSE-APACHE │ ├── LICENSE-MIT │ ├── README.md │ ├── benches │ ├── file.rs │ └── rust.rs │ ├── build.rs │ ├── codegen │ ├── Cargo.toml │ ├── README.md │ └── src │ │ ├── cfg.rs │ │ ├── clone.rs │ │ ├── css.rs │ │ ├── debug.rs │ │ ├── eq.rs │ │ ├── file.rs │ │ ├── fold.rs │ │ ├── full.rs │ │ ├── gen.rs │ │ ├── hash.rs │ │ ├── json.rs │ │ ├── lookup.rs │ │ ├── main.rs │ │ ├── operand.rs │ │ ├── parse.rs │ │ ├── snapshot.rs │ │ ├── version.rs │ │ ├── visit.rs │ │ ├── visit_mut.rs │ │ └── workspace_path.rs │ ├── dev │ ├── Cargo.toml │ ├── README.md │ ├── main.rs │ └── parse.rs │ ├── examples │ ├── README.md │ ├── dump-syntax │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ └── main.rs │ ├── heapsize │ │ ├── README.md │ │ ├── example │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── main.rs │ │ ├── heapsize │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── lib.rs │ │ └── heapsize_derive │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ └── lib.rs │ ├── lazy-static │ │ ├── README.md │ │ ├── example │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ │ └── main.rs │ │ └── lazy-static │ │ │ ├── Cargo.toml │ │ │ └── src │ │ │ └── lib.rs │ └── trace-var │ │ ├── README.md │ │ ├── example │ │ ├── Cargo.toml │ │ └── src │ │ │ └── main.rs │ │ └── trace-var │ │ ├── Cargo.toml │ │ └── src │ │ └── lib.rs │ ├── fuzz │ ├── .gitignore │ ├── Cargo.toml │ └── fuzz_targets │ │ ├── create_token_buffer.rs │ │ └── parse_file.rs │ ├── json │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── rustfmt.toml │ ├── src │ ├── attr.rs │ ├── bigint.rs │ ├── buffer.rs │ ├── classify.rs │ ├── custom_keyword.rs │ ├── custom_punctuation.rs │ ├── data.rs │ ├── derive.rs │ ├── discouraged.rs │ ├── drops.rs │ ├── error.rs │ ├── export.rs │ ├── expr.rs │ ├── ext.rs │ ├── file.rs │ ├── fixup.rs │ ├── gen │ │ ├── clone.rs │ │ ├── debug.rs │ │ ├── eq.rs │ │ ├── fold.rs │ │ ├── hash.rs │ │ ├── token.css │ │ ├── visit.rs │ │ └── visit_mut.rs │ ├── gen_helper.rs │ ├── generics.rs │ ├── group.rs │ ├── ident.rs │ ├── item.rs │ ├── lib.rs │ ├── lifetime.rs │ ├── lit.rs │ ├── lookahead.rs │ ├── mac.rs │ ├── macros.rs │ ├── meta.rs │ ├── op.rs │ ├── parse.rs │ ├── parse_macro_input.rs │ ├── parse_quote.rs │ ├── pat.rs │ ├── path.rs │ ├── precedence.rs │ ├── print.rs │ ├── punctuated.rs │ ├── restriction.rs │ ├── scan_expr.rs │ ├── sealed.rs │ ├── span.rs │ ├── spanned.rs │ ├── stmt.rs │ ├── thread.rs │ ├── token.rs │ ├── tt.rs │ ├── ty.rs │ ├── verbatim.rs │ ├── verus.rs │ └── whitespace.rs │ ├── syn.json │ └── tests │ ├── common │ ├── eq.rs │ ├── mod.rs │ ├── parse.rs │ └── visit.rs │ ├── debug │ ├── gen.rs │ └── mod.rs │ ├── features │ ├── Cargo.toml │ └── lib.rs │ ├── macros │ └── mod.rs │ ├── regression.rs │ ├── regression │ ├── issue1108.rs │ └── issue1235.rs │ ├── repo │ ├── mod.rs │ └── progress.rs │ ├── test_asyncness.rs │ ├── test_attribute.rs │ ├── test_derive_input.rs │ ├── test_expr.rs │ ├── test_generics.rs │ ├── test_grouping.rs │ ├── test_ident.rs │ ├── test_item.rs │ ├── test_iterators.rs │ ├── test_lit.rs │ ├── test_meta.rs │ ├── test_parse_buffer.rs │ ├── test_parse_quote.rs │ ├── test_parse_stream.rs │ ├── test_pat.rs │ ├── test_path.rs │ ├── test_precedence.rs │ ├── test_receiver.rs │ ├── test_round_trip.rs │ ├── test_shebang.rs │ ├── test_size.rs │ ├── test_stmt.rs │ ├── test_token_trees.rs │ ├── test_ty.rs │ ├── test_unparenthesize.rs │ ├── test_visibility.rs │ └── zzz_stable.rs ├── examples ├── README.md ├── adts.rs ├── adts_eq.rs ├── assert_by_compute.rs ├── assertions.rs ├── assorted_demo.rs ├── atomics.rs ├── basic_failure.rs ├── basic_lock1.rs ├── basic_lock2.rs ├── bitmap.rs ├── bitvector_basic.rs ├── bitvector_equivalence.rs ├── bitvector_garbage_collection.rs ├── broadcast_proof.rs ├── calc.rs ├── cargo-verus │ ├── library │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── run.sh │ └── test │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── cells.rs ├── datatypes.rs ├── debug.rs ├── debug_expand.rs ├── doubly_linked.rs ├── doubly_linked_xor.rs ├── even_cell.rs ├── exec_termination_example.rs ├── extensionality.rs ├── external.rs ├── fun_ext.rs ├── generics.rs ├── guide │ ├── assert_by_compute.rs │ ├── bst_map.rs │ ├── bst_map_generic.rs │ ├── bst_map_type_invariant.rs │ ├── calc.rs │ ├── datatypes.rs │ ├── equality.rs │ ├── ext_equal.rs │ ├── getting_started.rs │ ├── higher_order_fns.rs │ ├── integers.rs │ ├── interior_mutability.rs │ ├── invariants.rs │ ├── lib_examples.rs │ ├── modes.rs │ ├── nonlinear_bitvec.rs │ ├── overflow.rs │ ├── pervasive_example.rs │ ├── quants.rs │ ├── recursion.rs │ ├── requires_ensures.rs │ └── requires_ensures_edit.rs ├── imo_1988_6.rs ├── impl_basic.rs ├── integer_ring │ ├── circular_by_d.rs │ ├── integer_ring.rs │ └── integer_ring_bound_check.rs ├── integers.rs ├── invariants.rs ├── mergesort.rs ├── modules.rs ├── multiset.rs ├── nevd_script.rs ├── overflow.rs ├── pcm │ ├── agreement.rs │ ├── count_to_two.rs │ ├── log.rs │ ├── main.rs │ ├── monotonic_counter.rs │ └── oneshot.rs ├── playground.rs ├── power_of_2.rs ├── prelude.rs ├── proposal-rw2022.rs ├── quantifiers.rs ├── recommends.rs ├── recursion.rs ├── recursive_types.rs ├── rfmig_script.rs ├── rw2022_script.rs ├── rwlock_vstd.rs ├── scache │ └── rwlock.rs ├── set_from_vec.rs ├── state_machines │ ├── adder.rs │ ├── adder_generic.rs │ ├── adder_with_max.rs │ ├── arc.rs │ ├── conditional.rs │ ├── counting.rs │ ├── disk_example.rs │ ├── dist_rwlock.rs │ ├── flat_combine.rs │ ├── interner.rs │ ├── leader_election_complete.rs │ ├── maps.rs │ ├── petersons_algorithm.rs │ ├── reference-examples │ │ └── strategy_option.rs │ ├── refinement.rs │ ├── refinement_labels.rs │ ├── rwlock.rs │ ├── top_sort_dfs.rs │ └── tutorial │ │ ├── counting_to_2.rs │ │ ├── counting_to_n.rs │ │ ├── counting_to_n_atomic.rs │ │ ├── fifo.rs │ │ ├── pcell_example.rs │ │ ├── rc.rs │ │ ├── ref_cell.rs │ │ ├── unverified_counting_to_2.rs │ │ ├── unverified_counting_to_n │ │ ├── unverified_counting_to_n.rs │ │ ├── unverified_fifo.rs │ │ └── unverified_rc.rs ├── statements.rs ├── statics.rs ├── std_test │ ├── num.rs │ ├── option_test.rs │ ├── rc_test.rs │ ├── result.rs │ ├── template.rs │ ├── vec_test.rs │ └── vecdeque_test.rs ├── structural.rs ├── summer_school │ ├── chapter-1-22.rs │ ├── chapter-2-1.rs │ ├── chapter-2-2.rs │ ├── chapter-2-3.rs │ └── chapter-6-1.rs ├── syntax.rs ├── syntax_attr.rs ├── test.rs ├── test_expand_errors.rs ├── thread.rs ├── trait_for_fn.rs ├── traits.rs ├── trigger_loops.rs ├── vectors.rs └── verified_vec.rs ├── rust-toolchain.toml ├── source ├── .envrc ├── .gitignore ├── CODE.md ├── Cargo.lock ├── Cargo.toml ├── air │ ├── Cargo.toml │ └── src │ │ ├── ast.rs │ │ ├── ast_util.rs │ │ ├── block_to_assert.rs │ │ ├── closure.rs │ │ ├── context.rs │ │ ├── def.rs │ │ ├── emitter.rs │ │ ├── focus.rs │ │ ├── lib.rs │ │ ├── main.rs │ │ ├── messages.rs │ │ ├── model.rs │ │ ├── parser.rs │ │ ├── printer.rs │ │ ├── profiler.rs │ │ ├── scope_map.rs │ │ ├── singular_manager.rs │ │ ├── smt_process.rs │ │ ├── smt_verify.rs │ │ ├── tests.rs │ │ ├── typecheck.rs │ │ ├── util.rs │ │ ├── var_to_const.rs │ │ └── visitor.rs ├── builtin │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── builtin_macros │ ├── Cargo.toml │ └── src │ │ ├── atomic_ghost.rs │ │ ├── attr_block_trait.rs │ │ ├── attr_rewrite.rs │ │ ├── calc_macro.rs │ │ ├── enum_synthesize.rs │ │ ├── fndecl.rs │ │ ├── is_variant.rs │ │ ├── lib.rs │ │ ├── rustdoc.rs │ │ ├── struct_decl_inv.rs │ │ ├── structural.rs │ │ ├── syntax.rs │ │ └── topological_sort.rs ├── cargo-verus │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ └── main.rs ├── docs │ ├── guide │ │ ├── .gitignore │ │ ├── README.md │ │ ├── book.toml │ │ └── src │ │ │ ├── SUMMARY.md │ │ │ ├── assert_assume.md │ │ │ ├── assert_by.md │ │ │ ├── assert_by_compute.md │ │ │ ├── binary_search.md │ │ │ ├── bitvec.md │ │ │ ├── break.md │ │ │ ├── breaking_proofs_into_pieces.md │ │ │ ├── broadcast_proof.md │ │ │ ├── calc.md │ │ │ ├── call-from-unverified-code.md │ │ │ ├── calling-unverified-from-verified.md │ │ │ ├── calling-verified-from-unverified.md │ │ │ ├── char.md │ │ │ ├── checklist.md │ │ │ ├── complex_ownership.md │ │ │ ├── concurrency.md │ │ │ ├── const.md │ │ │ ├── container_bst.md │ │ │ ├── container_bst_all_source.md │ │ │ ├── container_bst_clone.md │ │ │ ├── container_bst_first_draft.md │ │ │ ├── container_bst_generic.md │ │ │ ├── container_bst_type_invariant.md │ │ │ ├── datatypes.md │ │ │ ├── datatypes_enum.md │ │ │ ├── datatypes_struct.md │ │ │ ├── develop_proofs.md │ │ │ ├── equality.md │ │ │ ├── exec_closures.md │ │ │ ├── exec_funs_as_values.md │ │ │ ├── exec_lib.md │ │ │ ├── exec_termination.md │ │ │ ├── exists.md │ │ │ ├── extensional_equality.md │ │ │ ├── features.md │ │ │ ├── for.md │ │ │ ├── forall.md │ │ │ ├── getting_started.md │ │ │ ├── getting_started_cmd_line.md │ │ │ ├── getting_started_vscode.md │ │ │ ├── ghost_vs_exec.md │ │ │ ├── graphics │ │ │ ├── verus-analyzer-error-example.png │ │ │ └── verusdoc-example.png │ │ │ ├── guarantees.md │ │ │ ├── higher-order-fns.md │ │ │ ├── ide_support.md │ │ │ ├── induction.md │ │ │ ├── install-singular.md │ │ │ ├── integers.md │ │ │ ├── interacting-with-unverified-code.md │ │ │ ├── interior_mutability.md │ │ │ ├── invariants.md │ │ │ ├── lex_mutual.md │ │ │ ├── memory-safety.md │ │ │ ├── modes.md │ │ │ ├── multitriggers.md │ │ │ ├── nonlinear.md │ │ │ ├── operators.md │ │ │ ├── overflow.md │ │ │ ├── overview.md │ │ │ ├── performance.md │ │ │ ├── pervasive.md │ │ │ ├── pointers.md │ │ │ ├── prefix-and-or.md │ │ │ ├── profiling.md │ │ │ ├── proof_functions.md │ │ │ ├── quantproofs.md │ │ │ ├── quants.md │ │ │ ├── recursion.md │ │ │ ├── recursion_loops.md │ │ │ ├── ref-extensional-equality.md │ │ │ ├── reference-as.md │ │ │ ├── reference-assert-by-bit-vector.md │ │ │ ├── reference-assert-by-compute.md │ │ │ ├── reference-assert-by-nonlinear.md │ │ │ ├── reference-assert-by.md │ │ │ ├── reference-assert-forall-by.md │ │ │ ├── reference-assume-specification.md │ │ │ ├── reference-at-sign.md │ │ │ ├── reference-attributes.md │ │ │ ├── reference-chained-op.md │ │ │ ├── reference-decreases-to.md │ │ │ ├── reference-decreases.md │ │ │ ├── reference-exec-signature.md │ │ │ ├── reference-flag-record.md │ │ │ ├── reference-global.md │ │ │ ├── reference-implication.md │ │ │ ├── reference-opens-invariants.md │ │ │ ├── reference-pointers-cells.md │ │ │ ├── reference-proof-signature.md │ │ │ ├── reference-recommends.md │ │ │ ├── reference-returns.md │ │ │ ├── reference-reveal-hide.md │ │ │ ├── reference-signature-fnonce.md │ │ │ ├── reference-signature-inheritance.md │ │ │ ├── reference-spec-index.md │ │ │ ├── reference-spec-signature.md │ │ │ ├── reference-type-invariants.md │ │ │ ├── reference-unions.md │ │ │ ├── reference-unwind-sig.md │ │ │ ├── reference-var-modes.md │ │ │ ├── requires_ensures.md │ │ │ ├── smt_failures.md │ │ │ ├── smt_perf_overview.md │ │ │ ├── spec-arithmetic.md │ │ │ ├── spec-bit-ops.md │ │ │ ├── spec-choose.md │ │ │ ├── spec-equality.md │ │ │ ├── spec-expressions.md │ │ │ ├── spec-operator-precedence.md │ │ │ ├── spec-quantifiers.md │ │ │ ├── spec-rust-subset.md │ │ │ ├── spec_closures.md │ │ │ ├── spec_functions.md │ │ │ ├── spec_lib.md │ │ │ ├── spec_vs_proof.md │ │ │ ├── specs.md │ │ │ ├── static.md │ │ │ ├── syntax.md │ │ │ ├── tcb.md │ │ │ ├── triangle.md │ │ │ ├── trigger-annotations.md │ │ │ ├── verus_macro_intro.md │ │ │ ├── verusdoc.md │ │ │ ├── vstd.md │ │ │ └── while.md │ ├── internal │ │ ├── modes.md │ │ ├── record-history.md │ │ ├── trait-implementation-notes.md │ │ ├── trait-notes.md │ │ └── wiki-archive │ │ │ ├── Deprecated-and-recommended-syntax-and-upcoming-changes.md │ │ │ ├── Goals.md │ │ │ ├── Home.md │ │ │ ├── Notes-on-Rust-ghost-types.md │ │ │ ├── README.md │ │ │ ├── Status-currently-supported-Rust-features.md │ │ │ ├── Verus-Retreat-2023.md │ │ │ └── Verus-Retreat-2024.md │ ├── project-goals.md │ ├── publications-and-projects │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── _config.yml │ │ ├── _layouts │ │ │ └── default.html │ │ ├── _projects │ │ │ ├── alpha-verus.md │ │ │ ├── anvil.md │ │ │ ├── atmosphere.md │ │ │ ├── auto-verus.md │ │ │ ├── beyond-isolation.md │ │ │ ├── ghost-linear.md │ │ │ ├── hance-thesis.md │ │ │ ├── ironfleet-kv.md │ │ │ ├── leaf.md │ │ │ ├── llm-mainstream.md │ │ │ ├── mimalloc.md │ │ │ ├── nr.md │ │ │ ├── persistent-storage.md │ │ │ ├── practical-foundation.md │ │ │ ├── proof-plumber.md │ │ │ ├── rag-verus.md │ │ │ ├── safe-verus.md │ │ │ ├── verified-ostd.md │ │ │ ├── verified-pagetable.md │ │ │ ├── verismo.md │ │ │ └── vest.md │ │ ├── award.jpg │ │ ├── css │ │ │ ├── base.css │ │ │ └── index.css │ │ └── index.md │ ├── state_machines │ │ ├── .gitignore │ │ ├── book.toml │ │ └── src │ │ │ ├── SUMMARY.md │ │ │ ├── birds-eye.md │ │ │ ├── components.md │ │ │ ├── examples │ │ │ ├── counting-to-2.md │ │ │ ├── counting-to-n-again.md │ │ │ ├── counting-to-n.md │ │ │ ├── hash-table.md │ │ │ ├── producer-consumer-queue.md │ │ │ ├── rc-exercises.md │ │ │ ├── rc.md │ │ │ ├── refcount.md │ │ │ ├── rust-counting-to-2.md │ │ │ ├── rust-counting-to-n.md │ │ │ ├── rust-producer-consumer-queue.md │ │ │ ├── rust-rc.md │ │ │ ├── rwlock.md │ │ │ ├── src-counting-to-2.md │ │ │ ├── src-counting-to-n.md │ │ │ ├── src-producer-consumer-queue.md │ │ │ └── src-rc.md │ │ │ ├── graphics │ │ │ ├── counting-to-n-diagram.png │ │ │ ├── fifo-head-tail.png │ │ │ ├── fifo-protocol-perspective.png │ │ │ ├── rc-ghost-diagram-ghost-only.png │ │ │ ├── rc-ghost-diagram.png │ │ │ └── strategy-reference-examples.png │ │ │ ├── high-level-idea.md │ │ │ ├── intro.md │ │ │ ├── invariants.md │ │ │ ├── macro-generated-reference.md │ │ │ ├── macro-high-level-reference.md │ │ │ ├── monoid-formalism.md │ │ │ ├── operations.md │ │ │ ├── properties.md │ │ │ ├── refinements-reference.md │ │ │ ├── state-machine-reference.md │ │ │ ├── strategy-bool.md │ │ │ ├── strategy-constant.md │ │ │ ├── strategy-count.md │ │ │ ├── strategy-map.md │ │ │ ├── strategy-multiset.md │ │ │ ├── strategy-not-tokenized.md │ │ │ ├── strategy-option.md │ │ │ ├── strategy-persistent-bool.md │ │ │ ├── strategy-persistent-map.md │ │ │ ├── strategy-persistent-option.md │ │ │ ├── strategy-reference.md │ │ │ ├── strategy-set.md │ │ │ ├── strategy-storage-map.md │ │ │ ├── strategy-storage-option.md │ │ │ ├── strategy-variable.md │ │ │ ├── token-exchanges-as-transitions.md │ │ │ ├── tokenization-reference.md │ │ │ ├── tokenized-overview.md │ │ │ ├── tokenized.md │ │ │ ├── transition-language.md │ │ │ └── tutorial-by-example.md │ ├── verus-demo.png │ ├── verus │ │ ├── .gitignore │ │ ├── Gemfile │ │ ├── Gemfile.lock │ │ ├── _config.yml │ │ ├── _layouts │ │ │ └── default.html │ │ ├── assets │ │ │ ├── verus-color.png │ │ │ ├── verus-color.svg │ │ │ ├── verus-gray.png │ │ │ ├── verus-gray.svg │ │ │ ├── verus-text-dark.svg │ │ │ └── verus-text-light.svg │ │ ├── css │ │ │ ├── base.css │ │ │ └── logo.css │ │ ├── jekyll-serve-docker.sh │ │ └── logo.html │ ├── vscode-demo.gif │ └── zulip-icon-circle.svg ├── lifetime_generate_works.txt ├── rust_verify │ ├── Cargo.toml │ ├── NOTES.md │ └── src │ │ ├── attributes.rs │ │ ├── automatic_derive.rs │ │ ├── buckets.rs │ │ ├── cargo_verus.rs │ │ ├── cargo_verus_dep_tracker.rs │ │ ├── commands.rs │ │ ├── config.rs │ │ ├── context.rs │ │ ├── debugger.rs │ │ ├── def.rs │ │ ├── driver.rs │ │ ├── erase.rs │ │ ├── expand_errors_driver.rs │ │ ├── external.rs │ │ ├── externs.rs │ │ ├── file_loader.rs │ │ ├── fn_call_to_vir.rs │ │ ├── hir_hide_reveal_rewrite.rs │ │ ├── import_export.rs │ │ ├── lib.rs │ │ ├── lifetime.rs │ │ ├── lifetime_ast.rs │ │ ├── lifetime_emit.rs │ │ ├── lifetime_generate.rs │ │ ├── main.rs │ │ ├── profiler.rs │ │ ├── resolve_traits.rs │ │ ├── reveal_hide.rs │ │ ├── rust_intrinsics_to_vir.rs │ │ ├── rust_to_vir.rs │ │ ├── rust_to_vir_adts.rs │ │ ├── rust_to_vir_base.rs │ │ ├── rust_to_vir_expr.rs │ │ ├── rust_to_vir_func.rs │ │ ├── rust_to_vir_global.rs │ │ ├── rust_to_vir_impl.rs │ │ ├── rust_to_vir_trait.rs │ │ ├── singular.rs │ │ ├── spans.rs │ │ ├── trait_conflicts.rs │ │ ├── user_filter.rs │ │ ├── util.rs │ │ ├── verifier.rs │ │ └── verus_items.rs ├── rust_verify_build_macros │ └── src │ │ └── bin │ │ └── build_vstd.rs ├── rust_verify_test │ ├── Cargo.toml │ └── tests │ │ ├── adts.rs │ │ ├── adts_generics.rs │ │ ├── adts_opaque.rs │ │ ├── arrays.rs │ │ ├── assert_bitvector_by.rs │ │ ├── assert_by_compute.rs │ │ ├── assert_forall_by.rs │ │ ├── assoc_type_impls.rs │ │ ├── atomic_lib.rs │ │ ├── atomics.rs │ │ ├── basic.rs │ │ ├── bitvector.rs │ │ ├── broadcast_forall.rs │ │ ├── calc.rs │ │ ├── cell_lib.rs │ │ ├── choose.rs │ │ ├── closures.rs │ │ ├── common │ │ └── mod.rs │ │ ├── consts.rs │ │ ├── control_flow.rs │ │ ├── dafny_axioms.rs │ │ ├── erase.rs │ │ ├── errors.rs │ │ ├── examples.rs │ │ ├── exec_closures.rs │ │ ├── exec_termination.rs │ │ ├── expand_errors.rs │ │ ├── expr_stmts.rs │ │ ├── ext_equal.rs │ │ ├── external_fn_specification.rs │ │ ├── external_traits.rs │ │ ├── external_type_specification.rs │ │ ├── fndef_types.rs │ │ ├── functions.rs │ │ ├── generics.rs │ │ ├── harness.rs │ │ ├── hash.rs │ │ ├── impl.rs │ │ ├── inline.rs │ │ ├── integer_ring.rs │ │ ├── integers.rs │ │ ├── layout.rs │ │ ├── let_else.rs │ │ ├── lifetime.rs │ │ ├── literals.rs │ │ ├── loops.rs │ │ ├── loops_no_spinoff.rs │ │ ├── maps.rs │ │ ├── marker_traits.rs │ │ ├── match.rs │ │ ├── modes.rs │ │ ├── modules.rs │ │ ├── multiset.rs │ │ ├── nested_items.rs │ │ ├── never_type.rs │ │ ├── no_cheating.rs │ │ ├── nonlinear.rs │ │ ├── opaque_reveal.rs │ │ ├── open_invariant.rs │ │ ├── overflow.rs │ │ ├── partial_eq.rs │ │ ├── proof_closures.rs │ │ ├── proph.rs │ │ ├── prophecy.rs │ │ ├── quantifiers.rs │ │ ├── raw_ptrs.rs │ │ ├── recommends.rs │ │ ├── recursion.rs │ │ ├── recursive_types.rs │ │ ├── refs.rs │ │ ├── regression.rs │ │ ├── results.rs │ │ ├── return.rs │ │ ├── returns_postcondition.rs │ │ ├── safe_api.rs │ │ ├── scope.rs │ │ ├── seqs.rs │ │ ├── sets.rs │ │ ├── size_of.rs │ │ ├── slices.rs │ │ ├── state_machines.rs │ │ ├── std.rs │ │ ├── strings.rs │ │ ├── structural.rs │ │ ├── summer_school.rs │ │ ├── syntax_attr.rs │ │ ├── traits.rs │ │ ├── traits_extend_ensures.rs │ │ ├── traits_modules.rs │ │ ├── traits_modules_pub_crate.rs │ │ ├── triggers.rs │ │ ├── ui.rs │ │ ├── unions.rs │ │ ├── unsafe.rs │ │ ├── unwind.rs │ │ ├── user_defined_type_invariants.rs │ │ ├── when_used_as_spec.rs │ │ └── z3_restart.rs ├── rust_verify_test_macros │ ├── Cargo.toml │ └── src │ │ ├── examples.rs │ │ ├── lib.rs │ │ └── rust_code.rs ├── rustfmt.toml ├── state_machines_macros │ ├── Cargo.toml │ └── src │ │ ├── ast.rs │ │ ├── case_macro.rs │ │ ├── check_bind_stmts.rs │ │ ├── check_birds_eye.rs │ │ ├── concurrency_tokens.rs │ │ ├── field_access_visitor.rs │ │ ├── ident_visitor.rs │ │ ├── inherent_safety_conditions.rs │ │ ├── lemmas.rs │ │ ├── lib.rs │ │ ├── parse_token_stream.rs │ │ ├── parse_transition.rs │ │ ├── safety_conditions.rs │ │ ├── self_type_visitor.rs │ │ ├── simplification.rs │ │ ├── simplify_asserts.rs │ │ ├── to_relation.rs │ │ ├── to_token_stream.rs │ │ ├── token_transition_checks.rs │ │ ├── transitions.rs │ │ ├── util.rs │ │ └── vstd_path.rs ├── tools │ ├── build-run-log.sh │ ├── docs.sh │ ├── get-cvc5.ps1 │ ├── get-cvc5.sh │ ├── get-z3.ps1 │ ├── get-z3.sh │ ├── internals_interface │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── line_count │ │ ├── .cargo │ │ │ └── config.toml │ │ ├── .gitignore │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ └── main.rs │ ├── minimizers │ │ ├── .gitignore │ │ ├── README.md │ │ ├── _common_string_search.sh │ │ ├── panicked_in.sh │ │ ├── rlimit_exceeded.sh │ │ └── time_exceeded.sh │ ├── qi-graph │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── index.html │ │ └── src │ │ │ └── main.rs │ ├── render-verus-log-call-graphs.sh │ ├── run-tests.sh │ └── rust-verify.sh ├── verus │ ├── Cargo.toml │ ├── build.rs │ └── src │ │ ├── main.rs │ │ ├── record.rs │ │ └── record_history.rs ├── verusdoc │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── vir │ ├── Cargo.toml │ └── src │ │ ├── assoc_types_to_air.rs │ │ ├── ast.rs │ │ ├── ast_simplify.rs │ │ ├── ast_sort.rs │ │ ├── ast_to_sst.rs │ │ ├── ast_to_sst_crate.rs │ │ ├── ast_to_sst_func.rs │ │ ├── ast_util.rs │ │ ├── ast_visitor.rs │ │ ├── autospec.rs │ │ ├── bitvector_to_air.rs │ │ ├── check_ast_flavor.rs │ │ ├── closures.rs │ │ ├── context.rs │ │ ├── datatype_to_air.rs │ │ ├── def.rs │ │ ├── early_exit_cf.rs │ │ ├── expand_errors.rs │ │ ├── headers.rs │ │ ├── heuristics.rs │ │ ├── interpreter.rs │ │ ├── inv_masks.rs │ │ ├── layout.rs │ │ ├── lib.rs │ │ ├── loop_inference.rs │ │ ├── messages.rs │ │ ├── modes.rs │ │ ├── poly.rs │ │ ├── prelude.rs │ │ ├── printer.rs │ │ ├── prune.rs │ │ ├── recursion.rs │ │ ├── recursive_types.rs │ │ ├── safe_api.rs │ │ ├── scc.rs │ │ ├── sst.rs │ │ ├── sst_elaborate.rs │ │ ├── sst_to_air.rs │ │ ├── sst_to_air_func.rs │ │ ├── sst_util.rs │ │ ├── sst_vars.rs │ │ ├── sst_visitor.rs │ │ ├── traits.rs │ │ ├── triggers.rs │ │ ├── triggers_auto.rs │ │ ├── unicode.rs │ │ ├── user_defined_type_invariants.rs │ │ ├── util.rs │ │ ├── visitor.rs │ │ └── well_formed.rs ├── vir_macros │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── vstd │ ├── Cargo.toml │ ├── README.md │ ├── arithmetic │ │ ├── README.md │ │ ├── div_mod.rs │ │ ├── internals │ │ │ ├── div_internals.rs │ │ │ ├── div_internals_nonlinear.rs │ │ │ ├── general_internals.rs │ │ │ ├── mod.rs │ │ │ ├── mod_internals.rs │ │ │ ├── mod_internals_nonlinear.rs │ │ │ ├── mul_internals.rs │ │ │ └── mul_internals_nonlinear.rs │ │ ├── logarithm.rs │ │ ├── mod.rs │ │ ├── mul.rs │ │ ├── overflow.rs │ │ ├── power.rs │ │ └── power2.rs │ ├── array.rs │ ├── atomic.rs │ ├── atomic_ghost.rs │ ├── bits.rs │ ├── build.rs │ ├── bytes.rs │ ├── calc_macro.rs │ ├── cell.rs │ ├── compute.rs │ ├── function.rs │ ├── hash_map.rs │ ├── hash_set.rs │ ├── invariant.rs │ ├── layout.rs │ ├── logatom.rs │ ├── map.rs │ ├── map_lib.rs │ ├── math.rs │ ├── modes.rs │ ├── multiset.rs │ ├── multiset_lib.rs │ ├── pcm.rs │ ├── pcm_lib.rs │ ├── pervasive.rs │ ├── prelude.rs │ ├── proph.rs │ ├── raw_ptr.rs │ ├── relations.rs │ ├── rwlock.rs │ ├── seq.rs │ ├── seq_lib.rs │ ├── set.rs │ ├── set_lib.rs │ ├── shared.rs │ ├── simple_pptr.rs │ ├── slice.rs │ ├── state_machine_internal.rs │ ├── std_specs │ │ ├── alloc.rs │ │ ├── atomic.rs │ │ ├── bits.rs │ │ ├── clone.rs │ │ ├── control_flow.rs │ │ ├── core.rs │ │ ├── hash.rs │ │ ├── mod.rs │ │ ├── num.rs │ │ ├── option.rs │ │ ├── range.rs │ │ ├── result.rs │ │ ├── smart_ptrs.rs │ │ ├── vec.rs │ │ └── vecdeque.rs │ ├── storage_protocol.rs │ ├── string.rs │ ├── thread.rs │ ├── tokens.rs │ ├── tokens │ │ └── frac.rs │ ├── view.rs │ └── vstd.rs └── vstd_build │ ├── Cargo.toml │ └── src │ └── main.rs └── tools ├── activate ├── activate.bat ├── activate.fish ├── activate.ps1 ├── common └── consts.rs ├── development ├── issues-fetch.py ├── issues-render-adopt-an-issue.py └── releases-fetch.py ├── shell.nix ├── vargo ├── .cargo │ └── config.toml ├── .gitignore ├── Cargo.lock ├── Cargo.toml └── src │ ├── main.rs │ └── util.rs └── veritas ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── build_images.sh ├── build_verus.sh ├── container-entrypoint.sh ├── get-z3.sh ├── push_images.sh ├── run.sh ├── run_configuration_all.toml ├── run_configuration_page_table.toml ├── run_configuration_vstd.toml ├── setup_container ├── src └── main.rs ├── verus-lang_veritas-1.82.0.dockerfile ├── verus-lang_verus-base-1.82.0.dockerfile └── verus-lang_verus-deps.dockerfile /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Format vstd with `verusfmt` version 0.2.3 2 | c5965bbf6f4a0493bb26b4b0df0ebb62af609f81 3 | # Format vstd with `verusfmt` version 0.2.7 4 | # With CI checks enabled, hopefully this is last of the ignored verusfmt 5 | 548664657ef279cbc2f7c0dc08d136c4475653ac 6 | # Format vstd with `verusfmt` version 0.2.7 7 | # now using source/rustfmt.toml settings 8 | c86127ac23fa8e7ad82bf9df44e77df3b886ff72 9 | # Format `calc!` statements 10 | eb89e2b8672ed2723e225529f8ca752aa67e0209 11 | # Rename examples directory (rename source/rust_verify/example to examples) 12 | 8707ef26789e8b734c2d5bfe6d866356314bd859 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve Verus 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 21 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | By submitting this pull request, I confirm that my contribution is made under the terms of the [MIT license](https://github.com/verus-lang/verus/blob/main/LICENSE). 4 | -------------------------------------------------------------------------------- /.github/workflows/get-z3.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | z3_version="4.12.5" 3 | 4 | filename=z3-$z3_version-x64-glibc-2.31 5 | wget https://github.com/Z3Prover/z3/releases/download/z3-$z3_version/$filename.zip 6 | unzip $filename.zip 7 | cp $filename/bin/z3 . 8 | 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /rust 2 | *.swp 3 | *.exe 4 | *.pdb 5 | /.vscode/settings.json 6 | /.vscode/launch.json 7 | /.vscode/tasks.json 8 | -------------------------------------------------------------------------------- /.vscode/settings.json.template: -------------------------------------------------------------------------------- 1 | // Copy to .vscode/settings.json and adjust as necessary 2 | { 3 | "rust-analyzer.cargo.buildScripts.enable": true, 4 | "rust-analyzer.cargo.features": ["record-history"], 5 | "rust-analyzer.cargo.extraEnv": { 6 | "RUSTC_BOOTSTRAP": "1", 7 | // flags for verus 8 | "RUSTFLAGS": "--cfg proc_macro_span --cfg verus_keep_ghost --cfg span_locations" 9 | // flags for line_count 10 | // "RUSTFLAGS": "--cfg proc_macro_span --cfg span_locations" 11 | }, 12 | "rust-analyzer.runnableEnv": { 13 | "RUSTC_BOOTSTRAP": "1" 14 | }, 15 | // Use .exe extension for Windows, otherwise remove 16 | "rust-analyzer.runnables.command": "../tools/vargo/target/release/vargo[.exe]", 17 | "rust-analyzer.procMacro.enable": true, 18 | "rust-analyzer.rustc.source": "discover", 19 | "rust-analyzer.workspace.symbol.search.scope": "workspace_and_dependencies", 20 | "rust-analyzer.diagnostics.disabled": ["unresolved-extern-crate", "syntax-error"] 21 | } 22 | 23 | // if you're developing a tool that doesn't link with verus, use the following instead 24 | // { 25 | // "rust-analyzer.linkedProjects": [ 26 | // "tools/veritas/Cargo.toml" 27 | // ] 28 | // } -------------------------------------------------------------------------------- /.vscode/tasks.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "label": "build", 6 | "type": "shell", 7 | "command": "bash -c 'cd source; . ../tools/activate && vargo build'", 8 | "problemMatcher": [], 9 | "group": { 10 | "kind": "build", 11 | "isDefault": true 12 | } 13 | }, 14 | { 15 | "label": "build-no-vstd", 16 | "type": "shell", 17 | "command": "bash -c 'cd source; . ../tools/activate && vargo build --exclude vstd'", 18 | "problemMatcher": [], 19 | "group": { 20 | "kind": "build", 21 | "isDefault": true 22 | } 23 | } 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 The Verus Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /dependencies/prettyplease/.gitattributes: -------------------------------------------------------------------------------- 1 | cargo-expand/*.rs linguist-generated 2 | examples/*.rs linguist-generated 3 | -------------------------------------------------------------------------------- /dependencies/prettyplease/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: dtolnay 2 | -------------------------------------------------------------------------------- /dependencies/prettyplease/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /Cargo.lock 3 | -------------------------------------------------------------------------------- /dependencies/prettyplease/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /dependencies/prettyplease/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::ffi::OsString; 3 | use std::process; 4 | 5 | fn main() { 6 | println!("cargo:rerun-if-changed=build.rs"); 7 | 8 | println!("cargo:rustc-check-cfg=cfg(exhaustive)"); 9 | println!("cargo:rustc-check-cfg=cfg(prettyplease_debug)"); 10 | println!("cargo:rustc-check-cfg=cfg(prettyplease_debug_indent)"); 11 | 12 | let pkg_version = cargo_env_var("CARGO_PKG_VERSION"); 13 | println!("cargo:VERSION={}", pkg_version.to_str().unwrap()); 14 | } 15 | 16 | fn cargo_env_var(key: &str) -> OsString { 17 | env::var_os(key).unwrap_or_else(|| { 18 | eprintln!("Environment variable ${key} is not set during execution of build script"); 19 | process::exit(1); 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /dependencies/prettyplease/cargo-expand/update/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "prettyplease-update" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [[bin]] 9 | name = "prettyplease-update" 10 | path = "update.rs" 11 | 12 | [dependencies] 13 | anyhow = "1.0" 14 | prettyplease = { path = "../../", features = ["verbatim"] } 15 | proc-macro2 = { version = "1.0", features = ["span-locations"] } 16 | syn = { version = "2.0", default-features = false, features = ["parsing", "printing"] } 17 | -------------------------------------------------------------------------------- /dependencies/prettyplease/cargo-expand/update/update.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{bail, Result}; 2 | use std::ffi::OsStr; 3 | use std::fs; 4 | use std::path::Path; 5 | 6 | fn main() -> Result<()> { 7 | let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR")); 8 | let cargo_expand_dir = manifest_dir.join(".."); 9 | 10 | for entry in fs::read_dir(cargo_expand_dir)? { 11 | let entry = entry?; 12 | let file_type = entry.file_type()?; 13 | if !file_type.is_file() { 14 | continue; 15 | } 16 | 17 | let path = entry.path(); 18 | if path.extension() != Some(OsStr::new("rs")) { 19 | continue; 20 | } 21 | 22 | let input_contents = fs::read_to_string(&path)?; 23 | let syntax_tree = match syn::parse_file(&input_contents) { 24 | Ok(syntax_tree) => syntax_tree, 25 | Err(err) => { 26 | let path = path.canonicalize().unwrap_or(path); 27 | let span = err.span().start(); 28 | bail!("{}:{}:{}\n{}", path.display(), span.line, span.column, err); 29 | } 30 | }; 31 | let string = prettyplease::unparse(&syntax_tree); 32 | fs::write(&path, string)?; 33 | } 34 | 35 | Ok(()) 36 | } 37 | -------------------------------------------------------------------------------- /dependencies/prettyplease/examples/.tokeignore: -------------------------------------------------------------------------------- 1 | *.rs 2 | -------------------------------------------------------------------------------- /dependencies/prettyplease/examples/update/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "prettyplease-update-examples" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [[bin]] 9 | name = "prettyplease-update-examples" 10 | path = "update-examples.rs" 11 | 12 | [dependencies] 13 | anyhow = "1.0" 14 | prettyplease = { path = "../../" } 15 | quote = { version = "1.0", default-features = false } 16 | syn = { version = "2.0", default-features = false, features = ["parsing", "printing"] } 17 | -------------------------------------------------------------------------------- /dependencies/prettyplease/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | /artifacts/ 2 | /corpus/ 3 | /coverage/ 4 | /target/ 5 | /Cargo.lock 6 | -------------------------------------------------------------------------------- /dependencies/prettyplease/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "prettyplease-fuzz" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [package.metadata] 9 | cargo-fuzz = true 10 | 11 | [dependencies] 12 | libfuzzer-sys = "0.4" 13 | prettyplease = { path = "..", features = ["verbatim"] } 14 | syn = { version = "2", default-features = false, features = ["full", "parsing"] } 15 | 16 | [[bin]] 17 | name = "round_trip" 18 | path = "fuzz_targets/round_trip.rs" 19 | test = false 20 | doc = false 21 | 22 | [workspace] 23 | -------------------------------------------------------------------------------- /dependencies/prettyplease/fuzz/fuzz_targets/round_trip.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use libfuzzer_sys::fuzz_target; 4 | use std::str; 5 | 6 | fuzz_target!(|data: &[u8]| { 7 | let ..=299 = data.len() else { return }; 8 | let Ok(string) = str::from_utf8(data) else { 9 | return; 10 | }; 11 | let Ok(syntax_tree) = syn::parse_file(string) else { 12 | return; 13 | }; 14 | let _ = prettyplease::unparse(&syntax_tree); 15 | }); 16 | -------------------------------------------------------------------------------- /dependencies/prettyplease/src/file.rs: -------------------------------------------------------------------------------- 1 | use crate::algorithm::Printer; 2 | use syn_verus::File; 3 | 4 | impl Printer { 5 | pub fn file(&mut self, file: &File) { 6 | self.cbox(0); 7 | if let Some(shebang) = &file.shebang { 8 | self.word(shebang.clone()); 9 | self.hardbreak(); 10 | } 11 | self.inner_attrs(&file.attrs); 12 | for item in &file.items { 13 | self.item(item); 14 | } 15 | self.end(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /dependencies/prettyplease/src/iter.rs: -------------------------------------------------------------------------------- 1 | use std::iter::Peekable; 2 | use std::ops::Deref; 3 | 4 | pub struct Delimited { 5 | is_first: bool, 6 | iter: Peekable, 7 | } 8 | 9 | pub trait IterDelimited: Iterator + Sized { 10 | fn delimited(self) -> Delimited { 11 | Delimited { 12 | is_first: true, 13 | iter: self.peekable(), 14 | } 15 | } 16 | } 17 | 18 | impl IterDelimited for I {} 19 | 20 | pub struct IteratorItem { 21 | value: T, 22 | pub is_first: bool, 23 | pub is_last: bool, 24 | } 25 | 26 | impl Iterator for Delimited { 27 | type Item = IteratorItem; 28 | 29 | fn next(&mut self) -> Option { 30 | let item = IteratorItem { 31 | value: self.iter.next()?, 32 | is_first: self.is_first, 33 | is_last: self.iter.peek().is_none(), 34 | }; 35 | self.is_first = false; 36 | Some(item) 37 | } 38 | } 39 | 40 | impl Deref for IteratorItem { 41 | type Target = T; 42 | 43 | fn deref(&self) -> &Self::Target { 44 | &self.value 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /dependencies/prettyplease/src/lifetime.rs: -------------------------------------------------------------------------------- 1 | use crate::algorithm::Printer; 2 | use syn_verus::Lifetime; 3 | 4 | impl Printer { 5 | pub fn lifetime(&mut self, lifetime: &Lifetime) { 6 | self.word("'"); 7 | self.ident(&lifetime.ident); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /dependencies/prettyplease/tests/test.rs: -------------------------------------------------------------------------------- 1 | use indoc::indoc; 2 | use proc_macro2::{Delimiter, Group, TokenStream}; 3 | use quote::quote; 4 | 5 | #[track_caller] 6 | fn test(tokens: TokenStream, expected: &str) { 7 | let syntax_tree: syn::File = syn::parse2(tokens).unwrap(); 8 | let pretty = prettyplease::unparse(&syntax_tree); 9 | assert_eq!(pretty, expected); 10 | } 11 | 12 | #[test] 13 | fn test_parenthesize_cond() { 14 | let s = Group::new(Delimiter::None, quote!(Struct {})); 15 | test( 16 | quote! { 17 | fn main() { 18 | if #s == #s {} 19 | } 20 | }, 21 | indoc! {" 22 | fn main() { 23 | if (Struct {}) == (Struct {}) {} 24 | } 25 | "}, 26 | ); 27 | } 28 | 29 | #[test] 30 | fn test_parenthesize_match_guard() { 31 | let expr_struct = Group::new(Delimiter::None, quote!(Struct {})); 32 | let expr_binary = Group::new(Delimiter::None, quote!(true && false)); 33 | test( 34 | quote! { 35 | fn main() { 36 | match () { 37 | () if let _ = #expr_struct => {} 38 | () if let _ = #expr_binary => {} 39 | } 40 | } 41 | }, 42 | indoc! {" 43 | fn main() { 44 | match () { 45 | () if let _ = Struct {} => {} 46 | () if let _ = (true && false) => {} 47 | } 48 | } 49 | "}, 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /dependencies/syn/.gitattributes: -------------------------------------------------------------------------------- 1 | src/gen/** linguist-generated 2 | syn.json linguist-generated 3 | tests/debug/gen.rs linguist-generated 4 | -------------------------------------------------------------------------------- /dependencies/syn/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: dtolnay 2 | -------------------------------------------------------------------------------- /dependencies/syn/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Cargo.lock 3 | /tests/rust/* 4 | /tests/*.pending-snap 5 | -------------------------------------------------------------------------------- /dependencies/syn/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Permission is hereby granted, free of charge, to any 2 | person obtaining a copy of this software and associated 3 | documentation files (the "Software"), to deal in the 4 | Software without restriction, including without 5 | limitation the rights to use, copy, modify, merge, 6 | publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software 8 | is furnished to do so, subject to the following 9 | conditions: 10 | 11 | The above copyright notice and this permission notice 12 | shall be included in all copies or substantial portions 13 | of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 16 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 17 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 18 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 19 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 22 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "syn-internal-codegen" 3 | version = "0.0.0" 4 | authors = ["David Tolnay ", "Nika Layzell "] 5 | edition = "2021" 6 | 7 | publish = false # this is an internal crate which should never be published 8 | 9 | [features] 10 | default = ["json"] 11 | json = ["syn-codegen/serde"] 12 | 13 | [dependencies] 14 | anyhow = "1" 15 | color-backtrace = "0.6" 16 | indexmap = { version = "2", features = ["serde"] } 17 | indoc = "2" 18 | inflections = "1.1" 19 | prettyplease = "0.2.3" 20 | proc-macro2 = { version = "1.0.20", features = ["span-locations"] } 21 | quote = "1" 22 | semver = { version = "1", features = ["serde"] } 23 | serde = "1.0.88" 24 | serde_json = "1.0.38" 25 | syn = { version = "2", features = ["derive", "full", "parsing", "printing"], default-features = false } 26 | syn-codegen = { path = "../json", default-features = false } 27 | toml = { version = "0.8", default-features = false, features = ["parse"] } 28 | 29 | [workspace] 30 | [patch.crates-io] 31 | syn_verus = { path = ".." } 32 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/README.md: -------------------------------------------------------------------------------- 1 | # syn_codegen 2 | 3 | This is an internal (not published on crates.io) crate which is used to generate 4 | the files in the `gen/` directory of `syn`. It is used to ensure that the 5 | implementations for `Fold`, `Visit`, and `VisitMut` remain in sync with the 6 | actual AST. 7 | 8 | To run this program, run `cargo run` in this directory, and the `gen/` folder 9 | will be re-generated. 10 | 11 | This program is slow, and is therefore not run when building `syn` as part of 12 | the build script to save on compile time. 13 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/cfg.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::TokenStream; 2 | use quote::quote; 3 | use syn_codegen::Features; 4 | 5 | pub enum DocCfg { 6 | Ordinary, 7 | Override(&'static str), 8 | None, 9 | } 10 | 11 | impl From<&'static str> for DocCfg { 12 | fn from(overriding_cfg: &'static str) -> Self { 13 | DocCfg::Override(overriding_cfg) 14 | } 15 | } 16 | 17 | pub fn features(features: &Features, doc_cfg: impl Into) -> TokenStream { 18 | let features = &features.any; 19 | let cfg = match features.len() { 20 | 0 => None, 21 | 1 => Some(quote! { cfg(feature = #(#features)*) }), 22 | _ => Some(quote! { cfg(any(#(feature = #features),*)) }), 23 | }; 24 | match (cfg, doc_cfg.into()) { 25 | (Some(cfg), DocCfg::Ordinary) => quote! { 26 | #[#cfg] 27 | #[cfg_attr(docsrs, doc(#cfg))] 28 | }, 29 | (Some(cfg), DocCfg::Override(overriding_cfg)) => quote! { 30 | #[#cfg] 31 | #[cfg_attr(docsrs, doc(cfg(feature = #overriding_cfg)))] 32 | }, 33 | (Some(cfg), DocCfg::None) => quote! { 34 | #[#cfg] 35 | }, 36 | (None, DocCfg::Override(overriding_cfg)) => quote! { 37 | #[cfg_attr(docsrs, doc(cfg(feature = #overriding_cfg)))] 38 | }, 39 | (None, DocCfg::Ordinary | DocCfg::None) => TokenStream::new(), 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/file.rs: -------------------------------------------------------------------------------- 1 | use crate::workspace_path; 2 | use anyhow::Result; 3 | use proc_macro2::TokenStream; 4 | use std::fs; 5 | use std::io::Write; 6 | use std::path::Path; 7 | 8 | pub fn write(relative_to_workspace_root: impl AsRef, content: TokenStream) -> Result<()> { 9 | let mut formatted = Vec::new(); 10 | writeln!( 11 | formatted, 12 | "// This file is @generated by syn-internal-codegen." 13 | )?; 14 | writeln!(formatted, "// It is not intended for manual editing.")?; 15 | writeln!(formatted)?; 16 | 17 | let syntax_tree: syn::File = syn::parse2(content).unwrap(); 18 | let pretty = prettyplease::unparse(&syntax_tree); 19 | write!(formatted, "{}", pretty)?; 20 | 21 | let path = workspace_path::get(relative_to_workspace_root); 22 | if path.is_file() && fs::read(&path)? == formatted { 23 | return Ok(()); 24 | } 25 | 26 | fs::write(path, formatted)?; 27 | Ok(()) 28 | } 29 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/gen.rs: -------------------------------------------------------------------------------- 1 | use crate::cfg::{self, DocCfg}; 2 | use inflections::Inflect; 3 | use proc_macro2::{Ident, Span, TokenStream}; 4 | use syn_codegen::{Data, Definitions, Features, Node}; 5 | 6 | pub const TERMINAL_TYPES: &[&str] = &["Span", "Ident"]; 7 | 8 | pub fn under_name(name: &str) -> Ident { 9 | Ident::new(&name.to_snake_case(), Span::call_site()) 10 | } 11 | 12 | pub fn traverse( 13 | defs: &Definitions, 14 | node: fn(&mut TokenStream, &mut TokenStream, &Node, &Definitions), 15 | ) -> (TokenStream, TokenStream) { 16 | let mut types = defs.types.clone(); 17 | for &terminal in TERMINAL_TYPES { 18 | types.push(Node { 19 | ident: terminal.to_owned(), 20 | features: Features::default(), 21 | data: Data::Private, 22 | exhaustive: true, 23 | }); 24 | } 25 | types.sort_by(|a, b| a.ident.cmp(&b.ident)); 26 | 27 | let mut traits = TokenStream::new(); 28 | let mut impls = TokenStream::new(); 29 | for s in types { 30 | let features = cfg::features(&s.features, DocCfg::Ordinary); 31 | traits.extend(features.clone()); 32 | impls.extend(features); 33 | node(&mut traits, &mut impls, &s, defs); 34 | } 35 | 36 | (traits, impls) 37 | } 38 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/json.rs: -------------------------------------------------------------------------------- 1 | use crate::workspace_path; 2 | use anyhow::Result; 3 | use std::fs; 4 | use syn_codegen::Definitions; 5 | 6 | pub fn generate(defs: &Definitions) -> Result<()> { 7 | let mut j = serde_json::to_string_pretty(&defs)?; 8 | j.push('\n'); 9 | 10 | let check: Definitions = serde_json::from_str(&j)?; 11 | assert_eq!(*defs, check); 12 | 13 | let json_path = workspace_path::get("syn.json"); 14 | fs::write(json_path, j)?; 15 | 16 | Ok(()) 17 | } 18 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/lookup.rs: -------------------------------------------------------------------------------- 1 | use syn_codegen::{Definitions, Node}; 2 | 3 | pub fn node<'a>(defs: &'a Definitions, name: &str) -> &'a Node { 4 | for node in &defs.types { 5 | if node.ident == name { 6 | return node; 7 | } 8 | } 9 | panic!("not found: {}", name) 10 | } 11 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/operand.rs: -------------------------------------------------------------------------------- 1 | use proc_macro2::TokenStream; 2 | use quote::quote; 3 | 4 | pub enum Operand { 5 | Borrowed(TokenStream), 6 | Owned(TokenStream), 7 | } 8 | 9 | pub use self::Operand::{Borrowed, Owned}; 10 | 11 | impl Operand { 12 | pub fn tokens(&self) -> &TokenStream { 13 | match self { 14 | Borrowed(n) | Owned(n) => n, 15 | } 16 | } 17 | 18 | pub fn ref_tokens(&self) -> TokenStream { 19 | match self { 20 | Borrowed(n) => n.clone(), 21 | Owned(n) => quote!(&#n), 22 | } 23 | } 24 | 25 | pub fn ref_mut_tokens(&self) -> TokenStream { 26 | match self { 27 | Borrowed(n) => n.clone(), 28 | Owned(n) => quote!(&mut #n), 29 | } 30 | } 31 | 32 | pub fn owned_tokens(&self) -> TokenStream { 33 | match self { 34 | Borrowed(n) => quote!(*#n), 35 | Owned(n) => n.clone(), 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/version.rs: -------------------------------------------------------------------------------- 1 | use crate::workspace_path; 2 | use anyhow::{Context as _, Result}; 3 | use semver::Version; 4 | use std::fs; 5 | use toml::Table; 6 | 7 | pub fn get() -> Result { 8 | let syn_cargo_toml = workspace_path::get("Cargo.toml"); 9 | let content = fs::read_to_string(syn_cargo_toml)?; 10 | let manifest: Table = toml::from_str(&content)?; 11 | manifest 12 | .get("package") 13 | .context("[package] not found in Cargo.toml")? 14 | .get("version") 15 | .and_then(toml::Value::as_str) 16 | .context("package version not found in Cargo.toml")? 17 | .parse() 18 | .context("failed to parse package version") 19 | } 20 | -------------------------------------------------------------------------------- /dependencies/syn/codegen/src/workspace_path.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | 3 | pub fn get(relative_to_workspace_root: impl AsRef) -> PathBuf { 4 | let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); 5 | assert!(path.pop()); 6 | path.push(relative_to_workspace_root); 7 | path 8 | } 9 | -------------------------------------------------------------------------------- /dependencies/syn/dev/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "syn-dev" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [lib] 9 | path = "parse.rs" 10 | proc-macro = true 11 | 12 | [[bin]] 13 | path = "main.rs" 14 | name = "syn-dev" 15 | 16 | [dependencies] 17 | quote = "1" 18 | 19 | [dependencies.syn_verus] 20 | default-features = false 21 | features = ["extra-traits", "full", "parsing", "proc-macro", "clone-impls", "printing"] 22 | path = ".." 23 | -------------------------------------------------------------------------------- /dependencies/syn/dev/README.md: -------------------------------------------------------------------------------- 1 | A little project skeleton for troubleshooting Syn's parsers during development, 2 | especially when adding support for new Rust syntax. 3 | 4 | Place a sample of the syntax you are working on into main.rs and then run `cargo 5 | check` to try parsing it, revealing the resulting syntax tree or else showing 6 | the position and error message if the input fails to parse. 7 | -------------------------------------------------------------------------------- /dependencies/syn/dev/main.rs: -------------------------------------------------------------------------------- 1 | syn_dev::r#mod! { 2 | // Write Rust code here and run `cargo check` to have Syn parse it. 3 | } 4 | -------------------------------------------------------------------------------- /dependencies/syn/dev/parse.rs: -------------------------------------------------------------------------------- 1 | use proc_macro::TokenStream; 2 | use quote::quote; 3 | use syn_verus::File; 4 | 5 | #[proc_macro] 6 | pub fn r#mod(input: TokenStream) -> TokenStream { 7 | let compile_error = syn_verus::parse::(input) 8 | .map(|file| println!("{:#?}", file)) 9 | .map_err(|err| err.to_compile_error()) 10 | .err(); 11 | 12 | TokenStream::from(quote! { 13 | #compile_error 14 | fn main() {} 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /dependencies/syn/examples/README.md: -------------------------------------------------------------------------------- 1 | ### [`dump-syntax`](dump-syntax) 2 | 3 | Little utility to parse a Rust source file into a `syn::File` and print out a 4 | debug representation of the syntax tree. 5 | 6 | ### [`heapsize`](heapsize) 7 | 8 | An example implementation of a derive macro that generates trait impls. 9 | 10 | ### [`lazy-static`](lazy-static) 11 | 12 | An example of parsing a custom syntax within a `functionlike!(...)` procedural 13 | macro. Demonstrates how to trigger custom warnings and error messages on 14 | individual tokens of the input. 15 | 16 | ### [`trace-var`](trace-var) 17 | 18 | An attribute procedural macro that uses a syntax tree traversal to transform 19 | certain syntax tree nodes in a function body. 20 | -------------------------------------------------------------------------------- /dependencies/syn/examples/dump-syntax/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dump-syntax" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | colored = "3" 10 | proc-macro2 = { version = "1", features = ["span-locations"] } 11 | 12 | [dependencies.syn] 13 | default-features = false 14 | features = ["extra-traits", "full", "parsing"] 15 | path = "../.." 16 | -------------------------------------------------------------------------------- /dependencies/syn/examples/dump-syntax/README.md: -------------------------------------------------------------------------------- 1 | Parse a Rust source file into a `syn::File` and print out a debug representation 2 | of the syntax tree. 3 | 4 | Use the following command from this directory to test this program by running it 5 | on its own source code: 6 | 7 | ``` 8 | cargo run -- src/main.rs 9 | ``` 10 | 11 | The output will begin with: 12 | 13 | ``` 14 | File { 15 | shebang: None, 16 | attrs: [ 17 | Attribute { 18 | pound_token: Pound, 19 | style: Inner( 20 | Bang 21 | ), 22 | bracket_token: Bracket, 23 | path: Path { 24 | leading_colon: None, 25 | segments: [ 26 | ... 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /dependencies/syn/examples/heapsize/example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "heapsize_example" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | heapsize = { path = "../heapsize" } 10 | -------------------------------------------------------------------------------- /dependencies/syn/examples/heapsize/example/src/main.rs: -------------------------------------------------------------------------------- 1 | use heapsize::HeapSize; 2 | 3 | #[derive(HeapSize)] 4 | struct Demo<'a, T: ?Sized> { 5 | a: Box, 6 | b: u8, 7 | c: &'a str, 8 | d: String, 9 | } 10 | 11 | fn main() { 12 | let demo = Demo { 13 | a: b"bytestring".to_vec().into_boxed_slice(), 14 | b: 255, 15 | c: "&'static str", 16 | d: "String".to_owned(), 17 | }; 18 | 19 | // 10 + 0 + 0 + 6 = 16 20 | println!( 21 | "heap size = {} + {} + {} + {} = {}", 22 | demo.a.heap_size_of_children(), 23 | demo.b.heap_size_of_children(), 24 | demo.c.heap_size_of_children(), 25 | demo.d.heap_size_of_children(), 26 | demo.heap_size_of_children() 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /dependencies/syn/examples/heapsize/heapsize/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "heapsize" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | heapsize_derive = { path = "../heapsize_derive" } 10 | -------------------------------------------------------------------------------- /dependencies/syn/examples/heapsize/heapsize_derive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "heapsize_derive" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [lib] 9 | proc-macro = true 10 | 11 | [dependencies] 12 | proc-macro2 = "1" 13 | quote = "1" 14 | syn = { path = "../../.." } 15 | -------------------------------------------------------------------------------- /dependencies/syn/examples/lazy-static/README.md: -------------------------------------------------------------------------------- 1 | An example of parsing a custom syntax within a `functionlike!(...)` procedural 2 | macro. Demonstrates how to trigger custom warnings and error messages on 3 | individual tokens of the input. 4 | 5 | - [`lazy-static/src/lib.rs`](lazy-static/src/lib.rs) 6 | - [`example/src/main.rs`](example/src/main.rs) 7 | 8 | The library implements a `lazy_static!` macro similar to the one from the real 9 | [`lazy_static`](https://docs.rs/lazy_static/1.0/lazy_static/) crate on 10 | crates.io. 11 | 12 | ```rust 13 | lazy_static! { 14 | static ref USERNAME: Regex = Regex::new("^[a-z0-9_-]{3,16}$").unwrap(); 15 | } 16 | ``` 17 | 18 | Compile and run the example by doing `cargo run` in the directory of the 19 | `example` crate. 20 | 21 | The implementation shows how to trigger custom warnings and error messages on 22 | the macro input. For example if you try adding an uncreatively named `FOO` lazy 23 | static, the macro will scold you with the following warning. 24 | 25 | ``` 26 | warning: come on, pick a more creative name 27 | --> src/main.rs:10:16 28 | | 29 | 10 | static ref FOO: String = "lazy_static".to_owned(); 30 | | ^^^ 31 | ``` 32 | 33 | And if you try to lazily initialize `() = ()`, the macro will outright refuse to 34 | compile it for you. 35 | 36 | ``` 37 | error: I can't think of a legitimate use for lazily initializing the value `()` 38 | --> src/main.rs:10:27 39 | | 40 | 10 | static ref UNIT: () = (); 41 | | ^^ 42 | ``` 43 | -------------------------------------------------------------------------------- /dependencies/syn/examples/lazy-static/example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lazy-static-example" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | lazy_static = { path = "../lazy-static" } 10 | regex = "1" 11 | -------------------------------------------------------------------------------- /dependencies/syn/examples/lazy-static/example/src/main.rs: -------------------------------------------------------------------------------- 1 | use lazy_static::lazy_static; 2 | use regex::Regex; 3 | 4 | lazy_static! { 5 | static ref USERNAME: Regex = { 6 | println!("Compiling username regex..."); 7 | Regex::new("^[a-z0-9_-]{3,16}$").unwrap() 8 | }; 9 | } 10 | 11 | fn main() { 12 | println!("Let's validate some usernames."); 13 | validate("fergie"); 14 | validate("will.i.am"); 15 | } 16 | 17 | fn validate(name: &str) { 18 | // The USERNAME regex is compiled lazily the first time its value is accessed. 19 | println!("is_match({:?}): {}", name, USERNAME.is_match(name)); 20 | } 21 | -------------------------------------------------------------------------------- /dependencies/syn/examples/lazy-static/lazy-static/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "lazy_static" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [lib] 9 | proc-macro = true 10 | 11 | [dependencies] 12 | proc-macro2 = { version = "1", features = ["nightly"] } 13 | quote = "1" 14 | syn = { path = "../../../", features = ["full"] } 15 | -------------------------------------------------------------------------------- /dependencies/syn/examples/trace-var/README.md: -------------------------------------------------------------------------------- 1 | An example of an attribute procedural macro. The `#[trace_var(...)]` attribute 2 | prints the value of the given variables each time they are reassigned. 3 | 4 | - [`trace-var/src/lib.rs`](trace-var/src/lib.rs) 5 | - [`example/src/main.rs`](example/src/main.rs) 6 | 7 | Consider the following factorial implementation. 8 | 9 | ```rust 10 | #[trace_var(p, n)] 11 | fn factorial(mut n: u64) -> u64 { 12 | let mut p = 1; 13 | while n > 1 { 14 | p *= n; 15 | n -= 1; 16 | } 17 | p 18 | } 19 | ``` 20 | 21 | Invoking this with `factorial(8)` prints all the values of `p` and `n` during 22 | the execution of the function. 23 | 24 | ``` 25 | p = 1 26 | p = 8 27 | n = 7 28 | p = 56 29 | n = 6 30 | p = 336 31 | n = 5 32 | p = 1680 33 | n = 4 34 | p = 6720 35 | n = 3 36 | p = 20160 37 | n = 2 38 | p = 40320 39 | n = 1 40 | ``` 41 | 42 | The procedural macro uses a syntax tree [`Fold`] to rewrite every `let` 43 | statement and assignment expression in the following way: 44 | 45 | [`Fold`]: https://docs.rs/syn/2.0/syn/fold/trait.Fold.html 46 | 47 | ```rust 48 | // Before 49 | let VAR = INIT; 50 | 51 | // After 52 | let VAR = { let VAR = INIT; println!("VAR = {:?}", VAR); VAR }; 53 | ``` 54 | 55 | ```rust 56 | // Before 57 | VAR = INIT 58 | 59 | // After 60 | { VAR = INIT; println!("VAR = {:?}", VAR); } 61 | ``` 62 | -------------------------------------------------------------------------------- /dependencies/syn/examples/trace-var/example/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "trace-var-example" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [dependencies] 9 | trace-var = { path = "../trace-var" } 10 | -------------------------------------------------------------------------------- /dependencies/syn/examples/trace-var/example/src/main.rs: -------------------------------------------------------------------------------- 1 | use trace_var::trace_var; 2 | 3 | fn main() { 4 | println!("{}", factorial(8)); 5 | } 6 | 7 | #[trace_var(p, n)] 8 | fn factorial(mut n: u64) -> u64 { 9 | let mut p = 1; 10 | while n > 1 { 11 | p *= n; 12 | n -= 1; 13 | } 14 | p 15 | } 16 | -------------------------------------------------------------------------------- /dependencies/syn/examples/trace-var/trace-var/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "trace-var" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [lib] 9 | proc-macro = true 10 | 11 | [dependencies] 12 | proc-macro2 = { version = "1", features = ["nightly"] } 13 | quote = "1" 14 | syn = { path = "../../../", features = ["fold", "full"] } 15 | -------------------------------------------------------------------------------- /dependencies/syn/fuzz/.gitignore: -------------------------------------------------------------------------------- 1 | /artifacts/ 2 | /corpus/ 3 | /coverage/ 4 | /target/ 5 | /Cargo.lock 6 | -------------------------------------------------------------------------------- /dependencies/syn/fuzz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "syn-fuzz" 3 | version = "0.0.0" 4 | authors = ["David Tolnay "] 5 | edition = "2021" 6 | publish = false 7 | 8 | [package.metadata] 9 | cargo-fuzz = true 10 | 11 | [dependencies] 12 | libfuzzer-sys = "0.4" 13 | proc-macro2 = "1.0.52" 14 | syn = { path = "..", default-features = false, features = ["full", "parsing"] } 15 | 16 | [features] 17 | span-locations = ["proc-macro2/span-locations"] 18 | 19 | [[bin]] 20 | name = "create_token_buffer" 21 | path = "fuzz_targets/create_token_buffer.rs" 22 | test = false 23 | doc = false 24 | 25 | [[bin]] 26 | name = "parse_file" 27 | path = "fuzz_targets/parse_file.rs" 28 | test = false 29 | doc = false 30 | 31 | [workspace] 32 | -------------------------------------------------------------------------------- /dependencies/syn/fuzz/fuzz_targets/create_token_buffer.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use libfuzzer_sys::fuzz_target; 4 | use proc_macro2::Span; 5 | use std::str; 6 | use syn::parse::{ParseStream, Parser}; 7 | 8 | fn immediate_fail(_input: ParseStream) -> syn::Result<()> { 9 | Err(syn::Error::new(Span::call_site(), "")) 10 | } 11 | 12 | fuzz_target!(|data: &[u8]| { 13 | if data.len() < 300 { 14 | if let Ok(string) = str::from_utf8(data) { 15 | let _ = immediate_fail.parse_str(string); 16 | } 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /dependencies/syn/fuzz/fuzz_targets/parse_file.rs: -------------------------------------------------------------------------------- 1 | #![no_main] 2 | 3 | use libfuzzer_sys::fuzz_target; 4 | use std::str; 5 | 6 | fuzz_target!(|data: &[u8]| { 7 | if data.len() < 300 { 8 | if let Ok(string) = str::from_utf8(data) { 9 | let _ = syn::parse_file(string); 10 | } 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /dependencies/syn/json/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "syn-codegen" 3 | version = "0.4.2" # also update html_root_url 4 | authors = ["David Tolnay "] 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 | 3 | 9 | 10 | Verus 11 | 12 | -------------------------------------------------------------------------------- /source/docs/verus/assets/verus-text-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | Verus 10 | 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>) { 11 | let x = t.view().get_Some_0(); 12 | } 13 | 14 | spec fn f2() -> bool { 15 | let x: Option = Option::None; 16 | x.is_None() 17 | } 18 | } => Ok(()) 19 | } 20 | 21 | test_verify_one_file! { 22 | #[test] test_regression_70 verus_code! { 23 | fn m(v: &mut u64) { } 24 | 25 | fn main() { 26 | let v = 6; 27 | m(&mut v); 28 | } 29 | } => Err(err) => assert_rust_error_msg(err, "cannot borrow `v` as mutable, as it is not declared as mutable") 30 | } 31 | -------------------------------------------------------------------------------- /source/rust_verify_test/tests/errors.rs: -------------------------------------------------------------------------------- 1 | #![feature(rustc_private)] 2 | #[macro_use] 3 | mod common; 4 | use common::*; 5 | 6 | test_verify_one_file! { 7 | #[test] test_387_discussioncomment_6202136 verus_code! { 8 | fn bar(v: Vec) { 9 | let bytes: &[u8] = &v[3 as usize .. 9 as usize]; 10 | } 11 | } => Err(err) => { 12 | assert_eq!(err.errors.len(), 1); 13 | assert!(err.errors[0].rendered.contains("Range")); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /source/rust_verify_test/tests/nested_items.rs: -------------------------------------------------------------------------------- 1 | #![feature(rustc_private)] 2 | #[macro_use] 3 | mod common; 4 | use common::*; 5 | 6 | test_verify_one_file! { 7 | #[test] test_ignorable_items verus_code! { 8 | mod m { 9 | // Verus can ignore 'use' item 10 | use super::*; 11 | 12 | pub open spec fn test() -> bool { true } 13 | } 14 | 15 | fn test_use_item() { 16 | use m::test as test2; 17 | assert(test2()); 18 | } 19 | 20 | fn test_macro_item() { 21 | let mut x = 1; 22 | 23 | // Verus can ignore 'macro' item 24 | macro_rules! add_1 { 25 | () => { 26 | x = x + 1; 27 | } 28 | } 29 | 30 | add_1!(); 31 | 32 | assert(x == 2); 33 | } 34 | } => Ok(()) 35 | } 36 | -------------------------------------------------------------------------------- /source/rust_verify_test/tests/partial_eq.rs: -------------------------------------------------------------------------------- 1 | #![feature(rustc_private)] 2 | #[macro_use] 3 | mod common; 4 | use common::*; 5 | 6 | test_verify_one_file! { 7 | // TODO: support floating point 8 | // NOTE (SOUNDNESS): need to make sure that executable code doesn't assume equality on NAN 9 | // (f32/f64 do not implement Structural) 10 | #[test] #[ignore] test_float_nan verus_code! { 11 | fn float_nan() { 12 | assert(f64::NAN == f64::NAN); // this should succeed (ghost equality) 13 | let n1 = f64::NAN; 14 | let n2 = f64::NAN; 15 | assert(n1 == n2); // this should succeed 16 | let b = (n1 == n2); // exec equality is not naive value equality; it's more complicated 17 | // this should fail: 18 | assert(b); // FAILS 19 | } 20 | } => Err(e) => assert_one_fails(e) 21 | } 22 | -------------------------------------------------------------------------------- /source/rust_verify_test/tests/ui.rs: -------------------------------------------------------------------------------- 1 | #![feature(rustc_private)] 2 | #[macro_use] 3 | mod common; 4 | use common::*; 5 | 6 | test_verify_one_file! { 7 | #[test] regression_114_unrelated_precondition verus_code! { 8 | fn get_bool() -> (b: bool) 9 | ensures b == true 10 | { 11 | true 12 | } 13 | 14 | fn require_false() -> bool 15 | requires false // INCORRECT CONTEXT 16 | { 17 | false 18 | } 19 | 20 | fn test() { 21 | let x = 6; 22 | 23 | if !get_bool() { 24 | require_false(); 25 | } 26 | 27 | assert(x == 7); // FAILS 28 | } 29 | } => Err(e) => { 30 | assert!(e.errors.len() == 1); 31 | assert!(!e.errors[0].spans.iter().any(|x| x.text[0].text.contains("INCORRECT CONTEXT"))); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /source/rust_verify_test/tests/unsafe.rs: -------------------------------------------------------------------------------- 1 | #![feature(rustc_private)] 2 | #[macro_use] 3 | mod common; 4 | use common::*; 5 | 6 | test_verify_one_file! { 7 | #[test] unsafe_fns_ok verus_code! { 8 | unsafe fn f() { 9 | } 10 | 11 | #[verifier::external] 12 | unsafe fn g() { 13 | } 14 | 15 | #[verifier::external_body] 16 | unsafe fn h() { 17 | } 18 | } => Ok(()) 19 | } 20 | 21 | test_verify_one_file! { 22 | #[test] unsafe_proof_fn_fail verus_code! { 23 | unsafe proof fn j() { 24 | } 25 | } => Err(err) => assert_vir_error_msg(err, "'unsafe' only makes sense on exec-mode functions") 26 | } 27 | -------------------------------------------------------------------------------- /source/rust_verify_test_macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rust_verify_test_macros" 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 | [lib] 9 | proc-macro = true 10 | 11 | [dependencies] 12 | quote = "*" 13 | syn = "*" 14 | proc-macro2 = "*" 15 | 16 | -------------------------------------------------------------------------------- /source/rust_verify_test_macros/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![feature(proc_macro_span)] 2 | #![feature(path_file_prefix)] 3 | 4 | mod examples; 5 | mod rust_code; 6 | 7 | use proc_macro::TokenStream; 8 | use quote::quote; 9 | 10 | #[proc_macro] 11 | pub fn code(input: TokenStream) -> TokenStream { 12 | let src = rust_code::rust_code_core(input); 13 | quote!(#src.to_string()).into() 14 | } 15 | 16 | #[proc_macro] 17 | pub fn verus_code(input: TokenStream) -> TokenStream { 18 | let src = "::builtin_macros::verus!{\n".to_string() + &rust_code::rust_code_core(input) + "}\n"; 19 | quote!(#src.to_string()).into() 20 | } 21 | 22 | #[proc_macro] 23 | pub fn code_str(input: TokenStream) -> TokenStream { 24 | let src = rust_code::rust_code_core(input); 25 | quote!(#src).into() 26 | } 27 | 28 | #[proc_macro] 29 | pub fn verus_code_str(input: TokenStream) -> TokenStream { 30 | let src = "::builtin_macros::verus!{\n".to_string() + &rust_code::rust_code_core(input) + "}\n"; 31 | quote!(#src).into() 32 | } 33 | 34 | #[proc_macro] 35 | pub fn examples_in_dir(input: TokenStream) -> TokenStream { 36 | examples::examples_in_dir(input) 37 | } 38 | -------------------------------------------------------------------------------- /source/rust_verify_test_macros/src/rust_code.rs: -------------------------------------------------------------------------------- 1 | // ACKNOWLEDGEMENT: adapted from Mara Bos' (@m_ou_se) https://blog.m-ou.se/writing-python-inside-rust-2/ 2 | 3 | use proc_macro::TokenStream; 4 | 5 | pub(crate) fn rust_code_core(input: TokenStream) -> String { 6 | let mut tokens = input.into_iter(); 7 | let mut span = tokens.next().unwrap().span(); 8 | while let Some(token) = tokens.next() { 9 | span = span.join(token.span()).unwrap(); 10 | } 11 | 12 | if let Some(src) = span.source_text() { 13 | let n = span.start().column() - 1; 14 | let original_src = src; 15 | let mut src = String::new(); 16 | let mut lines = original_src.lines(); 17 | src += lines.next().unwrap(); 18 | src += "\n"; 19 | for line in lines { 20 | let (indent, line) = line.split_at(n.min(line.len())); 21 | assert!(!indent.contains(|c| c != ' '), "Invalid indentation"); 22 | src += line; 23 | src += "\n"; 24 | } 25 | src 26 | } else { 27 | "panic!(\"source_text() returned None\")".to_string() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /source/rustfmt.toml: -------------------------------------------------------------------------------- 1 | # Copied from Rust compiler's rustfmt.toml settings 2 | 3 | # Run rustfmt with this config (it should be picked up automatically). 4 | # unstable_features=true # provided by vargo 5 | # version=Two # provided by vargo 6 | use_small_heuristics = "Max" 7 | merge_derives = false 8 | -------------------------------------------------------------------------------- /source/state_machines_macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "state_machines_macros" 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 | syn_verus = { path="../../dependencies/syn", features = ["full", "visit", "visit-mut", "extra-traits"] } 10 | quote = "1.0" 11 | proc-macro2 = "1.0" 12 | indexmap = { version = "1" } 13 | 14 | [lib] 15 | proc-macro = true 16 | 17 | [lints.rust] 18 | unexpected_cfgs = { level = "warn", check-cfg = ['cfg(verus_keep_ghost)'] } 19 | -------------------------------------------------------------------------------- /source/tools/build-run-log.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | color_blue="\x1B[1;94m" 4 | color_reset="\x1B[0m" 5 | 6 | if [ "$#" -ne 1 ]; then 7 | echo "$0" >&2 8 | echo " build on *nix, run the verifier on a single file with logging of air, vir, and smt to files in 'log/' in the same dire as the file" >&2 9 | echo "usage: $0 " >&2 10 | exit -1 11 | fi 12 | 13 | rs_file=$1 14 | rs_file_dir=`dirname "$rs_file"` 15 | rs_file_basename=`basename "$rs_file"` 16 | 17 | mkdir -p $rs_file_dir/log 18 | 19 | RUSTC=../rust/install/bin/rustc ../rust/install/bin/cargo build && \ 20 | ./tools/rust-verify.sh $rs_file \ 21 | --log-dir $rs_file_dir/log --log-all 22 | result=$? 23 | 24 | echo 25 | echo -e "${color_blue}logs${color_reset}" "$rs_file_dir/log" 26 | exit $? 27 | -------------------------------------------------------------------------------- /source/tools/get-cvc5.ps1: -------------------------------------------------------------------------------- 1 | $cvc5_version = "1.1.2" 2 | $filename = "cvc5-Win64-static" 3 | 4 | $download_url = "https://github.com/cvc5/cvc5/releases/download/cvc5-$cvc5_version/$filename.zip" 5 | Invoke-WebRequest -Uri $download_url -OutFile "$filename.zip" 6 | Expand-Archive -Path "$filename.zip" -DestinationPath "." 7 | Copy-Item "$filename/bin/cvc5.exe" -Destination "." 8 | Remove-Item -Recurse -Force "$filename" 9 | Remove-Item "$filename.zip" 10 | -------------------------------------------------------------------------------- /source/tools/get-cvc5.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash -eu 2 | 3 | cvc5_version="1.1.2" 4 | 5 | if [ `uname` == "Darwin" ]; then 6 | if [[ $(uname -m) == 'arm64' ]]; then 7 | filename="cvc5-macOS-arm64-static" 8 | else 9 | filename="cvc5-macOS-static" 10 | fi 11 | elif [ `uname` == "Linux" ]; then 12 | filename="cvc5-Linux-static" 13 | fi 14 | 15 | URL="https://github.com/cvc5/cvc5/releases/download/cvc5-$cvc5_version/$filename.zip" 16 | 17 | echo "Downloading: $URL" 18 | curl -L -o "$filename.zip" "$URL" 19 | unzip "$filename.zip" 20 | 21 | # delete the existing cvc5 because of caching issue on macs 22 | rm -f cvc5 23 | 24 | cp "$filename/bin/cvc5" . 25 | rm -r "$filename" 26 | rm "$filename.zip" 27 | -------------------------------------------------------------------------------- /source/tools/get-z3.ps1: -------------------------------------------------------------------------------- 1 | $z3_version = "4.12.5" 2 | $filename = "z3-$z3_version-x64-win" 3 | 4 | $download_url = "https://github.com/Z3Prover/z3/releases/download/z3-$z3_version/$filename.zip" 5 | Invoke-WebRequest -Uri $download_url -OutFile "$filename.zip" 6 | Expand-Archive -Path "$filename.zip" -DestinationPath "." 7 | Copy-Item "$filename/bin/z3.exe" -Destination "." 8 | Remove-Item -Recurse -Force "$filename" 9 | Remove-Item "$filename.zip" 10 | -------------------------------------------------------------------------------- /source/tools/get-z3.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash -eu 2 | 3 | z3_version="4.12.5" 4 | 5 | if [ `uname` == "Darwin" ]; then 6 | if [[ $(uname -m) == 'arm64' ]]; then 7 | filename="z3-$z3_version-arm64-osx-11.0" 8 | elif [[ $(uname -m) == 'x86_64' ]]; then 9 | filename="z3-$z3_version-x64-osx-11.7.10" 10 | else 11 | echo "Unsupported architecture $(uname -m)" 12 | exit -1 13 | fi 14 | elif [ `uname` == "Linux" ]; then 15 | if [[ $(uname -m) == 'aarch64' ]]; then 16 | filename="z3-$z3_version-arm64-glibc-2.35" 17 | elif [[ $(uname -m) == 'x86_64' ]]; then 18 | filename="z3-$z3_version-x64-glibc-2.31" 19 | else 20 | echo "Unsupported architecture $(uname -m)" 21 | exit -1 22 | fi 23 | fi 24 | 25 | URL="https://github.com/Z3Prover/z3/releases/download/z3-$z3_version/$filename.zip" 26 | 27 | echo "Downloading: $URL" 28 | curl -L -o "$filename.zip" "$URL" 29 | unzip "$filename.zip" 30 | 31 | # delete the existing z3 because of caching issue on macs 32 | rm -f z3 33 | 34 | cp "$filename/bin/z3" . 35 | rm -r "$filename" 36 | rm "$filename.zip" 37 | -------------------------------------------------------------------------------- /source/tools/internals_interface/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "internals_interface" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | serde = { version = "1", features = ["derive", "rc"] } 8 | bincode = "1.0.1" -------------------------------------------------------------------------------- /source/tools/line_count/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | rustflags = "--cfg proc_macro_span --cfg span_locations" 3 | 4 | [env] 5 | RUSTC_BOOTSTRAP = "1" 6 | -------------------------------------------------------------------------------- /source/tools/line_count/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /source/tools/line_count/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "line_count" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | syn_verus = { path = "../../../dependencies/syn", features = ["full", "visit", "visit-mut", "extra-traits"] } 10 | prettyplease_verus = { path = "../../../dependencies/prettyplease" } 11 | getopts = "*" 12 | toml = "0.8" 13 | serde = { version = "1.0", features = ["std", "derive", "rc"] } 14 | proc-macro2 = { version = "1.0.39", default-features = false } 15 | tabled = "0.14.0" 16 | serde_json = { version = "1.0", features = ["preserve_order"] } 17 | regex = "1.10" -------------------------------------------------------------------------------- /source/tools/minimizers/.gitignore: -------------------------------------------------------------------------------- 1 | foo.rs 2 | foo.rs.orig 3 | stderr 4 | -------------------------------------------------------------------------------- /source/tools/minimizers/panicked_in.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | exec ${DIR}/_common_string_search.sh ./foo.rs "panicked at" 5 | -------------------------------------------------------------------------------- /source/tools/minimizers/rlimit_exceeded.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | exec ${DIR}/_common_string_search.sh ./foo.rs 'Resource limit (rlimit) exceeded' 5 | -------------------------------------------------------------------------------- /source/tools/minimizers/time_exceeded.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)" 4 | exec ${DIR}/_common_string_search.sh ./foo.rs "has been running for" 5 | -------------------------------------------------------------------------------- /source/tools/qi-graph/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /source/tools/qi-graph/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "qi-graph" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /source/tools/qi-graph/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "qi-graph" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | serde = { version = "1", features = ["derive", "rc"] } 10 | bincode = "1.3" 11 | getopts = "*" 12 | petgraph = "0.5.1" 13 | serde_json = { version = "1", features = ["preserve_order"] } 14 | internals_interface = { path = "../internals_interface" } -------------------------------------------------------------------------------- /source/tools/render-verus-log-call-graphs.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -e 4 | 5 | for file in `ls .verus-log/*.dot`; do 6 | from=$file 7 | to="${file%.*}.pdf" 8 | set -x 9 | dot -Tpdf $from > $to 10 | set +x 11 | echo -e "$from -> \033[1;94m$to\033[0m" 12 | done 13 | -------------------------------------------------------------------------------- /source/tools/run-tests.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | set -e 4 | 5 | ./tools/cargo.sh nextest run "$@" 6 | -------------------------------------------------------------------------------- /source/verus/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "verus" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | toml = "0.7.4" 8 | zip = "0.6.6" 9 | chrono = "0.4.26" 10 | yansi = "0.5" 11 | serde_json = "1.0" 12 | regex = "1" 13 | git2 = { version = "0.18", optional = true, default-features = false, features = [] } 14 | is-terminal = { version = "0.4.9", optional = true } 15 | rand = { version = "0.8.0", optional = true } 16 | 17 | [features] 18 | default = [] 19 | record-history = ["git2", "is-terminal", "rand"] 20 | 21 | [target."cfg(windows)".dependencies] 22 | win32job = "1" 23 | 24 | [build-dependencies] 25 | regex = "1" 26 | -------------------------------------------------------------------------------- /source/verusdoc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "verusdoc" 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 | walkdir = "2.3.2" 10 | kuchiki = "0.8.1" 11 | serde_json = "1.0" 12 | serde = { version = "1.0", features = ["derive"] } 13 | html5ever = "0.25.2" 14 | -------------------------------------------------------------------------------- /source/vir/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vir" 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 -- VIR deliberately abstracts away from rustc's internals 9 | [dependencies] 10 | air = { path = "../air" } 11 | vir-macros = { path = "../vir_macros" } 12 | sise = "0.6.0" 13 | num-bigint = { version = "0.4.4", features = ["serde"] } 14 | num-traits= "0.2.16" 15 | im = "15.1.0" 16 | sha2 = "0.10.2" 17 | serde = { version = "1", features = ["derive", "rc"] } 18 | indexmap = { version = "1" } 19 | 20 | [features] 21 | singular = ["air/singular"] 22 | -------------------------------------------------------------------------------- /source/vir/src/unicode.rs: -------------------------------------------------------------------------------- 1 | use num_bigint::BigInt; 2 | use std::convert::TryFrom; 3 | 4 | // "A char is a 'Unicode scalar value', which is any 'Unicode code point' 5 | // other than a surrogate code point. This has a fixed numerical definition: 6 | // code points are in the range 0 to 0x10FFFF, inclusive. 7 | // Surrogate code points, used by UTF-16, are in the range 0xD800 to 0xDFFF." 8 | // 9 | // From https://doc.rust-lang.org/std/primitive.char.html 10 | 11 | pub const CHAR_RANGE_1_MIN: u32 = 0; 12 | pub const CHAR_RANGE_1_MAX: u32 = 0xD7FF; 13 | 14 | pub const CHAR_RANGE_2_MIN: u32 = 0xE000; 15 | pub const CHAR_RANGE_2_MAX: u32 = char::MAX as u32; 16 | 17 | fn valid_unicode_scalar(i: u32) -> bool { 18 | (CHAR_RANGE_1_MIN <= i && i <= CHAR_RANGE_1_MAX) 19 | || (CHAR_RANGE_2_MIN <= i && i <= CHAR_RANGE_2_MAX) 20 | } 21 | 22 | pub(crate) fn valid_unicode_scalar_bigint(i: &BigInt) -> bool { 23 | match u32::try_from(i) { 24 | Ok(x) => valid_unicode_scalar(x), 25 | Err(_) => false, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /source/vir_macros/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vir-macros" 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 -- VIR deliberately abstracts away from rustc's internals 9 | [dependencies] 10 | synstructure = "0.13" 11 | proc-macro2 = "*" 12 | syn = "^2" 13 | 14 | [lib] 15 | proc-macro = true 16 | -------------------------------------------------------------------------------- /source/vstd/Cargo.toml: -------------------------------------------------------------------------------- 1 | # This toml file is not part of the standard Verus workspace, 2 | # and is not required to build and use Verus. 3 | # Instead, it may optionally be used for compiling an erased vstd library 4 | # for linking with non-Verus Rust code. 5 | 6 | [package] 7 | name = "vstd" 8 | version = "0.1.0" 9 | edition = "2021" 10 | 11 | [lib] 12 | name = "vstd" 13 | path = "vstd.rs" 14 | 15 | [dependencies] 16 | builtin_macros = { path = "../builtin_macros" } 17 | builtin = { path = "../builtin" } 18 | state_machines_macros = { path = "../state_machines_macros" } 19 | 20 | [features] 21 | default = ["std"] 22 | std = ["alloc"] 23 | alloc = [] 24 | allocator = [] 25 | strict_provenance_atomic_ptr = [] 26 | allow_panic = [] # code is allowed to panic. 27 | 28 | 29 | [package.metadata.verus] 30 | verify = true 31 | is-vstd = true 32 | 33 | [lints.rust] 34 | unexpected_cfgs = { level = "warn", check-cfg = [ 35 | 'cfg(verus_keep_ghost)', 36 | 'cfg(verus_verify_core)', 37 | 'cfg(verus_keep_ghost_body)', 38 | ] } 39 | -------------------------------------------------------------------------------- /source/vstd/README.md: -------------------------------------------------------------------------------- 1 | Many of the definitions and lemmas in `seq_lib.rs`, `set_lib.rs`, `map_lib.rs`, and `multiset.rs` were adapted from the [Dafny standard libraries](https://github.com/dafny-lang/libraries/tree/master/src/Collections), which in turn were assembled from [Ironclad Apps](https://github.com/microsoft/Ironclad/tree/main/ironclad-apps), [IronFleet](https://github.com/microsoft/Ironclad/tree/main/ironfleet), [Vale](https://github.com/project-everest/vale/tree/legacy_dafny), [Verified BetrFS](https://github.com/vmware-labs/verified-betrfs), and [Verifying OpenTitan](https://github.com/secure-foundations/veri-titan). -------------------------------------------------------------------------------- /source/vstd/arithmetic/internals/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod div_internals_nonlinear; 2 | pub mod general_internals; 3 | pub mod mod_internals_nonlinear; 4 | pub mod mul_internals_nonlinear; 5 | 6 | pub mod div_internals; 7 | pub mod mod_internals; 8 | pub mod mul_internals; 9 | -------------------------------------------------------------------------------- /source/vstd/arithmetic/mod.rs: -------------------------------------------------------------------------------- 1 | mod internals; 2 | 3 | pub mod div_mod; 4 | pub mod logarithm; 5 | pub mod mul; 6 | pub mod overflow; 7 | pub mod power; 8 | pub mod power2; 9 | -------------------------------------------------------------------------------- /source/vstd/build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | const RUST_MIN_STACK_ENV: &str = "RUST_MIN_STACK"; 4 | 5 | const RUST_MIN_STACK_DEFAULT: u64 = 10 * 1024 * 1024; 6 | 7 | fn main() { 8 | let already_specified = match env::var_os(RUST_MIN_STACK_ENV) { 9 | None => false, 10 | Some(s) => !s.is_empty(), 11 | }; 12 | 13 | if !already_specified { 14 | println!("cargo:rustc-env={RUST_MIN_STACK_ENV}={RUST_MIN_STACK_DEFAULT}"); 15 | } 16 | 17 | println!("cargo:rerun-if-env-changed={RUST_MIN_STACK_ENV}"); 18 | } 19 | -------------------------------------------------------------------------------- /source/vstd/compute.rs: -------------------------------------------------------------------------------- 1 | use super::prelude::*; 2 | use core::ops::Range; 3 | 4 | verus! { 5 | 6 | /// Simplify proofs-by-computation for ranges of values 7 | pub trait RangeAll where Self: Sized { 8 | /// Checks whether `p` holds for all values in this range. 9 | /// See the [Verus tutorial](https://verus-lang.github.io/verus/guide/assert_by_compute.html) for example usage. 10 | spec fn all_spec(self, p: spec_fn(int) -> bool) -> bool; 11 | } 12 | 13 | pub open spec fn range_all_spec_rec(r: Range, p: spec_fn(int) -> bool) -> bool 14 | decreases r.end - r.start, 15 | { 16 | if r.start >= r.end { 17 | true 18 | } else { 19 | p(r.start) && range_all_spec_rec(r.start + 1..r.end, p) 20 | } 21 | } 22 | 23 | impl RangeAll for Range { 24 | open spec fn all_spec(self, p: spec_fn(int) -> bool) -> bool { 25 | range_all_spec_rec(self, p) 26 | } 27 | } 28 | 29 | pub broadcast proof fn all_spec_ensures(r: Range, p: spec_fn(int) -> bool) 30 | ensures 31 | #[trigger] r.all_spec(p) ==> (forall|i| r.start <= i < r.end ==> #[trigger] p(i)), 32 | decreases r.end - r.start, 33 | { 34 | if r.start >= r.end { 35 | } else { 36 | all_spec_ensures(r.start + 1..r.end, p); 37 | } 38 | } 39 | 40 | } // verus! 41 | -------------------------------------------------------------------------------- /source/vstd/modes.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused_imports)] 2 | use super::pervasive::*; 3 | #[allow(unused_imports)] 4 | use super::prelude::*; 5 | 6 | verus! { 7 | 8 | pub axiom fn tracked_swap(tracked a: &mut V, tracked b: &mut V) 9 | ensures 10 | a == old(b), 11 | b == old(a), 12 | ; 13 | 14 | /// Make any tracked object permanently shared and get a reference to it. 15 | /// 16 | /// Tip: If you try to use this and run into problems relating to the introduction 17 | /// of a lifetime variable, you want to try [`Shared`](crate::shared::Shared) instead. 18 | pub axiom fn tracked_static_ref(tracked v: V) -> (tracked res: &'static V) 19 | ensures 20 | res == v, 21 | ; 22 | 23 | } // verus! 24 | -------------------------------------------------------------------------------- /source/vstd/std_specs/alloc.rs: -------------------------------------------------------------------------------- 1 | use super::super::prelude::*; 2 | 3 | verus! { 4 | 5 | // this is a bit of a hack; verus treats Global specially already, 6 | // but putting this here helps Verus pick up all the trait impls for Global 7 | #[verifier::external_type_specification] 8 | #[verifier::external_body] 9 | pub struct ExGlobal(alloc::alloc::Global); 10 | 11 | } // verus! 12 | -------------------------------------------------------------------------------- /source/vstd/std_specs/clone.rs: -------------------------------------------------------------------------------- 1 | use super::super::prelude::*; 2 | use core::clone::Clone; 3 | 4 | verus! { 5 | 6 | #[verifier::external_trait_specification] 7 | pub trait ExClone: Sized { 8 | type ExternalTraitSpecificationFor: core::clone::Clone; 9 | 10 | fn clone(&self) -> Self; 11 | } 12 | 13 | /* 14 | #[verifier::external_fn_specification] 15 | pub fn ex_clone_clone_from(a: &mut T, b: &T) 16 | { 17 | a.clone_from(b) 18 | } 19 | */ 20 | 21 | pub assume_specification[ ::clone ](b: &bool) -> (res: bool) 22 | returns 23 | b, 24 | ; 25 | 26 | pub assume_specification[ ::clone ](c: &char) -> (res: char) 27 | returns 28 | c, 29 | ; 30 | 31 | #[allow(suspicious_double_ref_op)] 32 | pub assume_specification<'b, T: ?Sized, 'a>[ <&'b T as Clone>::clone ](b: &'a &'b T) -> (res: &'b T) 33 | ensures 34 | res == b, 35 | ; 36 | 37 | /* 38 | #[verifier::external_fn_specification] 39 | pub fn ex_bool_clone_from(dest: &mut bool, source: &bool) 40 | ensures *dest == source, 41 | { 42 | dest.clone_from(source) 43 | } 44 | */ 45 | 46 | // Cloning a Tracked copies the underlying ghost T 47 | pub assume_specification[ as Clone>::clone ](b: &Tracked) -> (res: Tracked< 48 | T, 49 | >) 50 | ensures 51 | res == b, 52 | ; 53 | 54 | pub assume_specification[ as Clone>::clone ](b: &Ghost) -> (res: Ghost) 55 | ensures 56 | res == b, 57 | ; 58 | 59 | } // verus! 60 | -------------------------------------------------------------------------------- /source/vstd/std_specs/mod.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "alloc")] 2 | pub mod alloc; 3 | 4 | pub mod atomic; 5 | pub mod bits; 6 | pub mod clone; 7 | pub mod control_flow; 8 | pub mod core; 9 | 10 | #[cfg(all(feature = "alloc", feature = "std"))] 11 | pub mod hash; 12 | 13 | pub mod num; 14 | pub mod option; 15 | pub mod range; 16 | pub mod result; 17 | 18 | #[cfg(feature = "alloc")] 19 | pub mod vec; 20 | 21 | #[cfg(feature = "alloc")] 22 | pub mod vecdeque; 23 | 24 | #[cfg(feature = "alloc")] 25 | pub mod smart_ptrs; 26 | 27 | // This struct is a hack that exists purely to create 28 | // a rustdoc page dedicated to 'assume_specification' specs 29 | pub struct VstdSpecsForRustStdLib; 30 | -------------------------------------------------------------------------------- /source/vstd/std_specs/smart_ptrs.rs: -------------------------------------------------------------------------------- 1 | use super::super::prelude::*; 2 | 3 | use alloc::boxed::Box; 4 | use alloc::rc::Rc; 5 | use alloc::sync::Arc; 6 | use alloc::vec::Vec; 7 | use core::alloc::Allocator; 8 | 9 | verus! { 10 | 11 | // TODO 12 | pub assume_specification[ <[T]>::into_vec ](b: Box<[T], A>) -> (v: Vec) 13 | ensures 14 | v@ == b@, 15 | ; 16 | 17 | pub assume_specification[ Box::::new ](t: T) -> (v: Box) 18 | ensures 19 | v == t, 20 | ; 21 | 22 | pub assume_specification[ Rc::::new ](t: T) -> (v: Rc) 23 | ensures 24 | v == t, 25 | ; 26 | 27 | pub assume_specification[ Arc::::new ](t: T) -> (v: Arc) 28 | ensures 29 | v == t, 30 | ; 31 | 32 | pub assume_specification[ as Clone>::clone ]( 33 | b: &Box, 34 | ) -> (res: Box) 35 | ensures 36 | cloned::(**b, *res), 37 | ; 38 | 39 | pub assume_specification[ Rc::::try_unwrap ](v: Rc) -> (result: Result< 40 | T, 41 | Rc, 42 | >) 43 | ensures 44 | match result { 45 | Ok(t) => t == v, 46 | Err(e) => e == v, 47 | }, 48 | ; 49 | 50 | pub assume_specification[ Rc::::into_inner ](v: Rc) -> (result: Option< 51 | T, 52 | >) 53 | ensures 54 | result matches Some(t) ==> t == v, 55 | ; 56 | 57 | } // verus! 58 | -------------------------------------------------------------------------------- /source/vstd_build/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vstd_build" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | [dependencies] 7 | yansi = "0.5" 8 | -------------------------------------------------------------------------------- /tools/activate: -------------------------------------------------------------------------------- 1 | unset -f cargo 2>/dev/null || true 2 | 3 | # Determine the directory that this script is in 4 | if [ "$BASH_VERSION" ]; then 5 | SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 6 | elif [ "$ZSH_VERSION" ]; then 7 | SCRIPT_DIR="$( cd "$( dirname "${(%):-%N}" )" >/dev/null 2>&1 && pwd )" 8 | else 9 | echo "Unknown shell; exiting." 10 | return 1 11 | fi 12 | 13 | echo "building vargo" 14 | ( 15 | cd "$SCRIPT_DIR/vargo" || exit 1 16 | cargo build --release || exit 1 17 | ) || return 1 18 | 19 | export PATH="$SCRIPT_DIR/vargo/target/release:$PATH" 20 | 21 | function cargo { 22 | echo "when working on Verus do not use cargo directly, use vargo instead" 1>&2 23 | echo "if you need to, you can still access cargo directly by starting a new shell without running the activate command" 1>&2 24 | return 1 25 | } 26 | -------------------------------------------------------------------------------- /tools/activate.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem Get the script's directory 4 | for %%i in (%0) do set SCRIPT_DIR=%%~dpi 5 | 6 | pushd "%SCRIPT_DIR%\vargo" 7 | cargo build --release 8 | popd 9 | 10 | set PATH=%SCRIPT_DIR%vargo\target\release;%PATH% 11 | -------------------------------------------------------------------------------- /tools/activate.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | 3 | functions --erase cargo 4 | 5 | # Get the script's directory 6 | set SCRIPT_DIR (realpath (dirname (status -f))) 7 | 8 | echo "building vargo" 9 | pushd $SCRIPT_DIR/vargo 10 | cargo build --release 11 | popd 12 | 13 | set -x PATH $SCRIPT_DIR/vargo/target/release $PATH 14 | 15 | function cargo 16 | echo "when working on Verus do not use cargo directly, use vargo instead" 1>&2 17 | echo "if you need to, you can still access cargo directly by starting a new shell without running the activate command" 1>&2 18 | return 1 19 | end 20 | -------------------------------------------------------------------------------- /tools/activate.ps1: -------------------------------------------------------------------------------- 1 | $ScriptDir = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition 2 | 3 | Push-Location -Path (Join-Path -Path $ScriptDir -ChildPath "vargo") 4 | cargo build --release 5 | Pop-Location 6 | 7 | $env:PATH = "$ScriptDir\vargo\target\release;$env:PATH" 8 | -------------------------------------------------------------------------------- /tools/common/consts.rs: -------------------------------------------------------------------------------- 1 | pub const EXPECTED_Z3_VERSION: &str = "4.12.5"; 2 | pub const EXPECTED_CVC5_VERSION: &str = "1.1.2"; 3 | #[allow(dead_code)] // actually used in `rust_verify/util.rs`, but missed by the dead code checker, possibly due to the use of `#[path(...)]` for this file 4 | pub const VERUS_GITHUB_BUG_REPORT_URL: &str = 5 | "https://github.com/verus-lang/verus/issues/new?template=bug_report.md"; 6 | -------------------------------------------------------------------------------- /tools/development/issues-fetch.py: -------------------------------------------------------------------------------- 1 | 2 | import requests 3 | import json 4 | 5 | # Replace with your personal access token 6 | GITHUB_TOKEN = 'github_pat_...' 7 | REPO_OWNER = 'verus-lang' 8 | REPO_NAME = 'verus' 9 | 10 | url = f'https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/issues' 11 | url += '?state=open' 12 | 13 | headers = { 14 | 'Authorization': f'token {GITHUB_TOKEN}', 15 | 'Accept': 'application/vnd.github.v3+json' 16 | } 17 | 18 | def fetch_issues(url): 19 | issues = [] 20 | while url: 21 | response = requests.get(url, headers=headers) 22 | response_data = response.json() 23 | issues.extend(response_data) 24 | 25 | if 'next' in response.links: 26 | url = response.links['next']['url'] 27 | else: 28 | url = None 29 | return issues 30 | 31 | all_issues = fetch_issues(url) 32 | all_issues = [i for i in all_issues if 'pull_request' not in i] 33 | 34 | with open('issues.json', 'w') as file: 35 | json.dump(all_issues, file, indent=4) 36 | 37 | print(f'Saved {len(all_issues)} issues to issues.json') 38 | -------------------------------------------------------------------------------- /tools/development/issues-render-adopt-an-issue.py: -------------------------------------------------------------------------------- 1 | import json 2 | import json 3 | import markdown 4 | 5 | with open('issues.json', 'r') as json_file: 6 | issues = json.load(json_file) 7 | 8 | md = "" 9 | 10 | for issue in issues: 11 | md += f"## [{issue['number']}]({issue['html_url']}) {issue['title']}\n" 12 | md += "\n" 13 | if len(issue['labels']) != 0: 14 | md += "**Labels**: " 15 | for label in issue['labels']: 16 | md += f"`{label['name']}` " 17 | md += "\n" 18 | if len(issue['assignees']) != 0: 19 | md += "**Assignees**: " 20 | for assignee in issue['assignees']: 21 | md += f"`{assignee['login']}` " 22 | md += "\n" 23 | md += "\n" 24 | md += "\n" 25 | md += "**Nominated as adoptable**: \n" 26 | md += "\n" 27 | md += "**Adopter**: \n" 28 | md += "\n" 29 | 30 | html = markdown.markdown(md) 31 | 32 | with open('issues.html', 'w') as file: 33 | file.write(html) -------------------------------------------------------------------------------- /tools/development/releases-fetch.py: -------------------------------------------------------------------------------- 1 | 2 | import requests 3 | import json 4 | 5 | GITHUB_TOKEN = 'github_pat_...' 6 | REPO_OWNER = 'verus-lang' 7 | REPO_NAME = 'verus' 8 | 9 | def fetch_all_releases(): 10 | url = f'https://api.github.com/repos/{REPO_OWNER}/{REPO_NAME}/releases' 11 | headers = { 12 | 'Authorization': f'token {GITHUB_TOKEN}', 13 | 'Accept': 'application/vnd.github.v3+json' 14 | } 15 | response = requests.get(url, headers=headers) 16 | response.raise_for_status() 17 | return response.json() 18 | 19 | all_releases = fetch_all_releases() 20 | with open('releases.json', 'w') as file: 21 | json.dump(all_releases, file, indent=4) 22 | 23 | print(f'Saved {len(all_releases)} releases to releases.json') -------------------------------------------------------------------------------- /tools/shell.nix: -------------------------------------------------------------------------------- 1 | # Minimal set of build requirements for Verus 2 | # 3 | # Open a shell which has access to nothing but these requirements using 4 | # nix-shell --pure tools/shell.nix 5 | # from the root of the repository. 6 | 7 | { pkgs ? import {} }: 8 | pkgs.mkShell { 9 | nativeBuildInputs = with pkgs; [ 10 | rustup 11 | unzip 12 | wget 13 | ]; 14 | } 15 | -------------------------------------------------------------------------------- /tools/vargo/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | # Set target directory in case it was overridden by the environment 2 | # https://doc.rust-lang.org/cargo/reference/config.html 3 | 4 | [build] 5 | target-dir = "target" 6 | -------------------------------------------------------------------------------- /tools/vargo/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | -------------------------------------------------------------------------------- /tools/vargo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vargo" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | serde = { version = "1", features = ["derive"] } 8 | serde_json = "1" 9 | regex = "1" 10 | yansi = "0.5" 11 | toml = "0.7" 12 | walkdir = "2.2" 13 | filetime = "0.2.9" -------------------------------------------------------------------------------- /tools/veritas/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /output/ 3 | -------------------------------------------------------------------------------- /tools/veritas/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "veritas-runner" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | [dependencies] 7 | git2 = "0.18" 8 | chrono = "0.4" 9 | yansi = "1.0" 10 | sha2 = "0.10" 11 | base64 = "0.22" 12 | serde = { version = "1.0", features = ["std", "derive"] } 13 | getopts = "0.2" 14 | toml = "0.8" 15 | regex = "1.10.4" 16 | serde_json = "1.0.116" 17 | -------------------------------------------------------------------------------- /tools/veritas/README.md: -------------------------------------------------------------------------------- 1 | NOTE: Veritas is highly experimental at this stage. It should already be useful, 2 | but it is likely to break when encountering unexpected situations. 3 | 4 | Veritas is a rust crater-alike tool to run a version of verus on a number of projects, 5 | generating a report of verification success/failures and verification performance data. 6 | 7 | Running veritas requires docker (or another container runtime). 8 | You can start a run with `bash run.sh path_to_run_configuration.toml`. 9 | There is an example run configuration in this directory. 10 | Running that command will start an ephemeral container and will create four 11 | permanent docker volumes: `verus-veritas-cargo-cache`, `verus-veritas-repo-cache`, 12 | `verus-veritas-rustup`, `verus-veritas-z3-cache`. These volumes cache dowloaded repositories, 13 | binaries, and other files, to reduce unnecessary traffic when performing multiple runs. -------------------------------------------------------------------------------- /tools/veritas/build_images.sh: -------------------------------------------------------------------------------- 1 | 2 | set -e 3 | set -x 4 | 5 | if [ "$(dirname "$0")" != "." ]; then 6 | echo "Please run the script from its directory." 7 | exit 1 8 | fi 9 | 10 | docker build -f verus-lang_verus-deps.dockerfile -t ghcr.io/utaal/verus-lang/verus-deps . 11 | docker build -f verus-lang_verus-base-1.82.0.dockerfile -t ghcr.io/utaal/verus-lang/verus-base:rust-1.82.0 . 12 | docker build -f verus-lang_veritas-1.82.0.dockerfile -t ghcr.io/utaal/verus-lang/veritas:rust-1.82.0 . 13 | -------------------------------------------------------------------------------- /tools/veritas/build_verus.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -x 3 | 4 | unset RUSTUP_TOOLCHAIN 5 | cd source 6 | 7 | # TODO restore once line_count is fixed 8 | # pushd tools/line_count 9 | # cargo build --release 10 | # popd 11 | 12 | . ../tools/activate 13 | # ./tools/get-z3.sh 14 | echo $RUSTUP_TOOLCHAIN 15 | vargo build --release $VERUS_FEATURES_ARGS 16 | -------------------------------------------------------------------------------- /tools/veritas/container-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | . /root/.cargo/env 4 | 5 | export VERUS_SINGULAR_PATH=/usr/bin/Singular 6 | 7 | # cargo run --release -- $@ 8 | cargo run -- $@ -------------------------------------------------------------------------------- /tools/veritas/get-z3.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | set -x 3 | 4 | z3_version=$1 5 | destination=$2 6 | 7 | if [ ! `uname` == "Linux" ]; then 8 | echo "unexpected OS" 9 | exit 1 10 | fi 11 | 12 | filename=z3-$z3_version-x64-glibc-2.31 13 | 14 | wget https://github.com/Z3Prover/z3/releases/download/z3-$z3_version/$filename.zip 15 | unzip $filename.zip 16 | 17 | cp $filename/bin/z3 $destination 18 | rm -r $filename 19 | rm $filename.zip -------------------------------------------------------------------------------- /tools/veritas/push_images.sh: -------------------------------------------------------------------------------- 1 | 2 | set -e 3 | set -x 4 | 5 | if [ "$(dirname "$0")" != "." ]; then 6 | echo "Please run the script from its directory." 7 | exit 1 8 | fi 9 | 10 | docker push ghcr.io/utaal/verus-lang/verus-deps 11 | docker push ghcr.io/utaal/verus-lang/verus-base:rust-1.82.0 12 | docker push ghcr.io/utaal/verus-lang/veritas:rust-1.82.0 13 | -------------------------------------------------------------------------------- /tools/veritas/run.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | if [ "$(dirname "$0")" != "." ]; then 4 | echo "Please run the script from its directory." 5 | exit 1 6 | fi 7 | 8 | docker run --platform=linux/amd64 \ 9 | -v verus-veritas-repo-cache:/root/repos-cache \ 10 | -v $(pwd):/root/veritas \ 11 | -v /root/work \ 12 | -v verus-veritas-cargo-cache:/root/.cargo \ 13 | -v verus-veritas-z3-cache:/root/z3-cache \ 14 | -v verus-veritas-rustup:/root/.rustup \ 15 | -v $(pwd)/output:/root/output \ 16 | --rm \ 17 | ghcr.io/utaal/verus-lang/veritas:rust-1.82.0 $@ 18 | -------------------------------------------------------------------------------- /tools/veritas/run_configuration_page_table.toml: -------------------------------------------------------------------------------- 1 | verus_git_url = "https://github.com/verus-lang/verus.git" 2 | verus_revspec = "main" 3 | verus_features = ["singular"] 4 | verus_verify_vstd = false 5 | 6 | [[project]] 7 | name = "page-table" 8 | git_url = "https://github.com/utaal/verified-nrkernel.git" 9 | revspec = "main" 10 | crate_root = "page-table/src/lib.rs" 11 | extra_args = ["--crate-type=lib", "--rlimit", "60"] 12 | 13 | -------------------------------------------------------------------------------- /tools/veritas/run_configuration_vstd.toml: -------------------------------------------------------------------------------- 1 | verus_git_url = "https://github.com/verus-lang/verus.git" 2 | verus_revspec = "main" 3 | verus_features = ["singular"] 4 | 5 | -------------------------------------------------------------------------------- /tools/veritas/setup_container: -------------------------------------------------------------------------------- 1 | export REPOS_CACHE_PATH=/root/repos-cache/ 2 | export Z3_CACHE_PATH=/root/z3-cache/ 3 | export WORKDIR_PATH=/root/work/ 4 | export OUTPUT_PATH=/root/output/ 5 | 6 | export VERUS_SINGULAR_PATH=/usr/bin/Singular -------------------------------------------------------------------------------- /tools/veritas/verus-lang_veritas-1.82.0.dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 ghcr.io/utaal/verus-lang/verus-base:rust-1.82.0 2 | 3 | VOLUME /root/veritas 4 | 5 | VOLUME /root/repos-cache 6 | VOLUME /root/z3-cache 7 | VOLUME /root/work 8 | VOLUME /root/output 9 | VOLUME /root/.rustup 10 | 11 | ENV REPOS_CACHE_PATH=/root/repos-cache/ 12 | ENV Z3_CACHE_PATH=/root/z3-cache/ 13 | ENV WORKDIR_PATH=/root/work/ 14 | ENV OUTPUT_PATH=/root/output/ 15 | 16 | WORKDIR /root/veritas 17 | ENTRYPOINT ["/bin/bash", "container-entrypoint.sh"] 18 | -------------------------------------------------------------------------------- /tools/veritas/verus-lang_verus-base-1.82.0.dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 ghcr.io/utaal/verus-lang/verus-deps 2 | 3 | RUN /root/.cargo/bin/rustup install 1.82.0 4 | -------------------------------------------------------------------------------- /tools/veritas/verus-lang_verus-deps.dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 ubuntu:24.04 2 | 3 | RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \ 4 | build-essential curl wget singular git unzip openssh-client pkg-config libssl-dev 5 | 6 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain none 7 | --------------------------------------------------------------------------------