Bazel rules for Rocq/Coq theorem proving and Rust formal verification with hermetic toolchain support via Nix.
- Rust → Rocq → Proofs: Complete pipeline from Rust code to verified proofs
- rocq-of-rust Integration: Translate Rust to Rocq via rocq-of-rust
- Hermetic Toolchains: Rocq 9.0, coqutil, Hammer, smpl via nixpkgs
- Cross-Platform: Linux, macOS (Intel & Apple Silicon)
- Bazel 8 bzlmod: Modern module system support
Nix is required for the Rocq toolchain.
macOS:
sh <(curl -L https://nixos.org/nix/install)
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
nix --versionLinux:
sh <(curl -L https://nixos.org/nix/install) --daemon
nix --versionOn Linux, rocq-of-rust requires Rust nightly with rustc internals:
# Install nightly toolchain
rustup toolchain install nightly-2024-12-01
# Add required components
rustup component add rustc-dev rust-src --toolchain nightly-2024-12-01
# Set library path for LLVM (add to ~/.bashrc or ~/.zshrc)
export LIBRARY_PATH="$(rustc +nightly-2024-12-01 --print sysroot)/lib:$LIBRARY_PATH"On macOS, Nix provides the complete Rust toolchain automatically.
bazel_dep(name = "rules_rocq_rust", version = "0.1.0")
git_override(
module_name = "rules_rocq_rust",
remote = "https://github.com/pulseengine/rules_rocq_rust.git",
commit = "<latest-commit>",
)
# Configure Rocq toolchain
rocq = use_extension("@rules_rocq_rust//rocq:extensions.bzl", "rocq")
rocq.toolchain()
use_repo(rocq, "rocq_toolchains", "rocq_stdlib", "rocq_coqutil", "rocq_hammer", "rocq_hammer_tactics", "rocq_smpl")
register_toolchains("@rocq_toolchains//:all")
# Configure rocq-of-rust
rocq_of_rust = use_extension("@rules_rocq_rust//coq_of_rust:extensions.bzl", "rocq_of_rust")
rocq_of_rust.toolchain(use_real_library = True)
use_repo(rocq_of_rust, "rocq_of_rust_toolchains", "rocq_of_rust_source")
register_toolchains("@rocq_of_rust_toolchains//:all")// point.rs
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Point { pub x: i32, pub y: i32 }
impl Point {
pub fn origin() -> Self { Point { x: 0, y: 0 } }
pub fn new(x: i32, y: i32) -> Self { Point { x, y } }
}load("@rules_rocq_rust//coq_of_rust:defs.bzl", "rocq_rust_verified_library")
load("@rules_rocq_rust//rocq:defs.bzl", "rocq_library")
# One-liner: translate and compile
rocq_rust_verified_library(
name = "point_verified",
rust_sources = ["point.rs"],
extra_flags = ["-impredicative-set"],
)
# Write proofs about the Rust code
rocq_library(
name = "point_proofs",
srcs = ["point_proofs.v"],
deps = [":point_verified"],
extra_flags = ["-impredicative-set"],
)bazel build //:point_proofsCompiles Rocq .v files to .vo.
rocq_library(
name = "my_proofs",
srcs = ["proof.v"],
deps = [":other_library"],
include_path = "MyProject", # Logical path prefix
extra_flags = ["-impredicative-set"],
)| Attribute | Description |
|---|---|
srcs |
Rocq source files (.v) |
deps |
Dependencies on other rocq_library targets |
include_path |
Logical path for this library (default: package path) |
extra_flags |
Extra flags passed to coqc |
Translates Rust source files to Rocq.
coq_of_rust_library(
name = "translated",
rust_sources = ["lib.rs"],
edition = "2021",
)| Attribute | Description |
|---|---|
rust_sources |
Rust source files to translate |
edition |
Rust edition (default: "2021") |
Convenience macro: translates Rust to Rocq and compiles.
rocq_rust_verified_library(
name = "verified",
rust_sources = ["lib.rs"],
edition = "2021",
deps = [], # Additional Rocq dependencies
extra_flags = ["-impredicative-set"],
)Test rule that verifies proofs compile successfully.
rocq_proof_test(
name = "proofs_test",
srcs = ["proofs.v"],
deps = [":proofs"],
)rocq_of_rust.toolchain(
use_real_library = True, # Use full RocqOfRust library (recommended)
fail_on_error = True, # Fail if rocq-of-rust build fails (default: True)
rust_nightly = "nightly-2024-12-01", # Rust nightly version
)| Option | Description |
|---|---|
use_real_library |
Use full RocqOfRust library with coqutil/hammer/smpl |
fail_on_error |
Fail build if rocq-of-rust cannot be built |
rust_nightly |
Rust nightly version for building rocq-of-rust |
The Rust nightly compiler bundles its own LLVM. Set LIBRARY_PATH:
export LIBRARY_PATH="$(rustc +nightly-2024-12-01 --print sysroot)/lib:$LIBRARY_PATH"Install Rust via rustup:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shInstall the required nightly components:
rustup component add rustc-dev rust-src --toolchain nightly-2024-12-01By default, builds fail loudly. If you see placeholder output, check the build logs for the actual error. To debug, run:
bazel build @rocq_of_rust_source//:rocq_of_rust_main --verbose_failuresEnsure the translated code compiled successfully first:
bazel build //:point_compiledThen check that your proof imports match the generated module names.
See examples/rust_to_rocq/ for a complete working example:
point.rs- Rust source with Point and Rectangle structsadvanced.rs- Generics, traits, lifetimes, enumspoint_proofs.v- Formal proofs about the translated code
# Build all examples
bazel build //examples/rust_to_rocq:point_proofs
bazel build //examples/rust_to_rocq:advanced_verified
# Run proof tests
bazel test //examples/rust_to_rocq:point_proofs_test- rocq-of-rust translates Rust source to Rocq using a deeply embedded monadic DSL
- coqc compiles the translated
.vfiles with the RocqOfRust library - You write proofs in Rocq that reason about the translated Rust semantics
- Proofs are machine-checked by the Rocq type system
| Component | Description |
|---|---|
| Rocq 9.0 | Core theorem prover |
| coqutil | Utility library |
| Hammer | Automated proof tactics |
| smpl | Simplification tactics |
| rocq-of-rust | Rust-to-Rocq translator (pinned version) |
| Platform | Status |
|---|---|
| Linux x86_64 | ✅ |
| Linux aarch64 | ✅ |
| macOS x86_64 | ✅ |
| macOS aarch64 | ✅ |
Apache License 2.0 - See LICENSE
- rocq-of-rust - Rust to Rocq translator
- nixpkgs - Nix packages
- Rocq Prover - The Rocq theorem prover