Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/hermes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ env:
jobs:
hermes_tests:
name: Hermes Tests
runs-on: ubuntu-latest
runs-on: ubuntu-24.04-64core
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
Expand All @@ -49,7 +49,7 @@ jobs:
run: |
set -eo pipefail
CHARON_TOOLCHAIN="$(cargo metadata --no-deps --format-version 1 \
| jq -r '.packages[] | select(.name == "cargo-hermes") | .metadata.hermes.dependencies.charon.rust_toolchain')"
| jq -r '.packages[] | select(.name == "cargo-hermes") | .metadata.build_rs.charon_rust_toolchain')"
rustup toolchain install "$CHARON_TOOLCHAIN"

- name: Install elan (Lean toolchain manager)
Expand Down
28 changes: 16 additions & 12 deletions tools/hermes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ regex.workspace = true
strip-ansi-escapes = "0.2.1"
similar = "2.7.0"

[package.metadata.build-rs]
[package.metadata.build_rs]

# The commit hash of the Aeneas repository to use.
#
# FIXME: Add a CI step to verify that this commit exists and matches the
# toolchain version.
aeneas_rev = "5918d4719139b5e5ae6e7b63f584b036620b41b7"
aeneas_rev = "1180be60c7a0e642cb442bfe90fe5cd8c1bb853f"

# The Lean toolchain version to use. This must match the version of Lean used
# by Aeneas in the `lean-toolchain` file in the commit above.
Expand All @@ -94,27 +94,31 @@ lean_toolchain = "leanprover/lean4:v4.28.0-rc1"
# version/commit ID once that's supported
charon_version = "0.1.174"

# The Rust toolchain required by Charon.
#
# FIXME(#3165):
# - Roll this from `tools/roll-pinned-prebuilts.py`
# - Auto-install via `rustup` during `cargo hermes setup`
charon_rust_toolchain = "nightly-2026-02-07"

[package.metadata.hermes.dependencies.aeneas]
# The per-commit release tag from AeneasVerif/charon
tag = "build-2026.03.24.085418-5918d4719139b5e5ae6e7b63f584b036620b41b7"
tag = "build-2026.03.29.102514-1180be60c7a0e642cb442bfe90fe5cd8c1bb853f"

[package.metadata.hermes.dependencies.aeneas.checksums]
linux-x86_64 = "fd706bf0f39701953d9d8734e9b0a9b8a6c9e71111006d093516748974a0d09a"
linux-x86_64-aeneas = "1ed68728e18299ba961bc76c0c4897e582fdcfe30ec9b01919e250dc3cb6e65d"
linux-x86_64 = "8224c76225329c8852e5a8cacf21fee9dc8bf93141a2a9a6ee2a52e3cfc2213f"
linux-x86_64-aeneas = "0efc2c1c2f695e8e8fc268e6d3aaa20b7bf0a52790250f6ac45dd5f261d52a82"
linux-x86_64-charon = "bcdc1ef536f863f21367973bd639e5557d36872cd9135d4b13ff84c2bc6df836"
linux-x86_64-charon-driver = "20379b2051dd51dbea8d720e4041d55afe9241b95ab911e3b06492110450ecd0"
macos-aarch64 = "d8284bf025cb768aa24cf49bdb66d6723f3c266d9ac95870bd5099d7db677e64"
macos-aarch64-aeneas = "85f9bbda808c764095fae086e35214e485f40e4c9666f6b84916481e5c7263f8"
macos-aarch64 = "7a5e9ded37dd21b288dffc68686ea4d254864c7a6b58a49d0bddab44d721114e"
macos-aarch64-aeneas = "079a6565a1b5ec142548e50cc32db25ce05ae9ee97ee7148da2cb80d7286bd4e"
macos-aarch64-charon = "6510ace82180cd78875b0631638a200d8e55bc9090c9372ea1dc8eb08511b6fb"
macos-aarch64-charon-driver = "3c11fcb6c5cd65cd14d9747c7f8ddd1522b608a1e79041c907cb79d3118054b2"
macos-x86_64 = "72ab5f3a22f7e666acd4c954600f4d963e34e22b900f222ce26b267939a0b4d2"
macos-x86_64-aeneas = "72a9078abeb9c989f07da25a7f541f01e0ad62214a9475e27d24cf58ebd8a740"
macos-x86_64 = "a909c3aa7813dd5f32b481d0c96e2b5ea3a729fa1898470b993055e778576459"
macos-x86_64-aeneas = "7a001aa2b9f786a3978a25a68291dd0f56c0c4f069b59b782f7fb84ab206a49e"
macos-x86_64-charon = "926c5ff8495c19b7a6f3aff1a3861970bae11bd374cf114ac3924a27bcae9ee7"
macos-x86_64-charon-driver = "03e6617fe122f29111bf16538a5ba8f0beac6698ce473d99069439d30fa552e8"

[package.metadata.hermes.dependencies.charon]
rust_toolchain = "nightly-2025-01-26"

[[test]]
name = "integration"
harness = false
7 changes: 4 additions & 3 deletions tools/hermes/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,19 @@ fn main() {
let cargo_toml: toml::Value =
toml::from_str(&cargo_toml_content).expect("failed to parse Cargo.toml");

// We expect the metadata to be under `[package.metadata.build-rs]`.
// We expect the metadata to be under `[package.metadata.build_rs]`.
let build_rs_metadata = cargo_toml
.get("package")
.and_then(|p| p.get("metadata"))
.and_then(|m| m.get("build-rs"))
.expect("Cargo.toml must have [package.metadata.build-rs] section");
.and_then(|m| m.get("build_rs"))
.expect("Cargo.toml must have [package.metadata.build_rs] section");

// Key in `Cargo.toml` -> Environment variable name
let vars = [
("aeneas_rev", "HERMES_AENEAS_REV"),
("lean_toolchain", "HERMES_LEAN_TOOLCHAIN"),
("charon_version", "HERMES_CHARON_EXPECTED_VERSION"),
("charon_rust_toolchain", "HERMES_CHARON_RUST_TOOLCHAIN"),
];

for (key, env_var) in vars {
Expand Down
13 changes: 12 additions & 1 deletion tools/hermes/examples/const_generics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
/// ```lean, hermes, spec
/// ```hermes
/// isValid self := N > 0
/// ```
pub struct ConstGen<const N: usize>;

/// ```hermes
/// isSafe : N > 0
/// ```
pub unsafe trait ConstTrait<const N: usize> {}

/// ```hermes
/// ensures: if N.val = 0 then ret.val = 0 else True
/// ```
pub fn use_const<const N: usize>(arr: [u8; N]) -> u8 {
if N > 0 { arr[0] } else { 0 }
Expand Down
5 changes: 1 addition & 4 deletions tools/hermes/src/charon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,10 +288,7 @@ fn check_charon_version(toolchain: &crate::setup::Toolchain) -> Result<()> {
/// installed via rustup. If it is missing, we provide a helpful error message
/// with the installation command.
fn check_rustup_toolchain() -> Result<()> {
// FIXME: We should probably parse this from Charon's metadata or a central
// place. For now, it's pinned to a specific nightly in Charon's build.
// In the future, Hermes could also manage the rustup toolchain.
let nightly_version = "nightly-2025-01-26";
let nightly_version = env!("HERMES_CHARON_RUST_TOOLCHAIN");

let output = Command::new("rustup")
.args(["toolchain", "list"])
Expand Down
Binary file modified tools/hermes/testdata/setup/aeneas-linux-x86_64.tar.gz
Binary file not shown.
Binary file modified tools/hermes/testdata/setup/aeneas-macos-aarch64.tar.gz
Binary file not shown.
Binary file modified tools/hermes/testdata/setup/aeneas-macos-x86_64.tar.gz
Binary file not shown.
4 changes: 3 additions & 1 deletion tools/hermes/tests/fixtures/associated_types/hermes.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Behavior: Compiles a Rust source featuring a trait with an associated type (`T::
"""

[test]
# FIXME(#3089): Update to use valid syntax in `lib.rs`; coalesce with
# `test_4_6_assoc_types`.
expected_status = "known_bug"
stderr_file = "expected.stderr"
expected_status = "failure"
args = ["verify", "--allow-sorry"]
16 changes: 0 additions & 16 deletions tools/hermes/tests/fixtures/design_doc/expected.stderr

This file was deleted.

9 changes: 0 additions & 9 deletions tools/hermes/tests/fixtures/design_doc/hermes.toml

This file was deleted.

8 changes: 0 additions & 8 deletions tools/hermes/tests/fixtures/design_doc/source/Cargo.toml

This file was deleted.

73 changes: 0 additions & 73 deletions tools/hermes/tests/fixtures/design_doc/source/src/lib.rs

This file was deleted.

2 changes: 1 addition & 1 deletion tools/hermes/tests/fixtures/duplicate_blocks/hermes.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ Behavior: Declares a single function with two consecutive `/// ```lean, hermes`
"""

[test]
expected_status = "failure"
stderr_file = "expected.stderr"
args = ["verify", "--allow-sorry"]
expected_status = "failure"
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ Behavior: In an `isValid` boundary condition, queries the default instantiation
"""

[test]
expected_status = "failure"
# FIXME(#3089): Update the syntax in `lib.rs` to be valid Lean, and get this
# passing.
expected_status = "known_bug"
args = ["verify", "--allow-sorry", "--unsound-allow-is-valid"]
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ pub trait Iter {
type Item: Default;
}

/// ```lean, hermes
/// ```hermes
/// proof (h_progress):
/// sorry
/// proof context:
Expand All @@ -13,8 +13,9 @@ pub fn check_item<T: Iter>(x: T::Item) -> T::Item {
x
}

/// @spec
/// ```hermes
/// isValid self := self.val == T::Item::default()
/// ```
pub struct Wrapper<T: Iter> where T::Item: PartialEq {
pub val: T::Item,
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ Behavior: Asserts that `fn theorem()`, `fn match()`, etc. are strictly escaped i
"""

[test]
expected_status = "failure"
# FIXME(#3089): This should succeed
expected_status = "known_bug"
args = ["verify", "--allow-sorry"]
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ Behavior: Uses Rust keywords natively (`r#match`, `r#type`). Confirms Charon saf
"""

[test]
expected_status = "failure"
expected_status = "known_bug"
args = ["verify", "--allow-sorry"]
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ Behavior: Utilizes explicit zero-sized structs and the common `()` unit type to
"""

[test]
expected_status = "failure"
args = ["verify", "--allow-sorry"]
# FIXME(#3089): This should succeed.
expected_status = "known_bug"
args = ["verify", "--allow-sorry", "--unsound-allow-is-valid"]
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@

/// ```hermes
/// isValid self := True
/// ```
pub struct Empty {}

/// ```hermes
/// isValid self := True
/// ```
pub struct WrapUnit {
pub f: (),
}

/// ```lean, hermes
/// proof (h_progress):
/// sorry
/// proof context:
/// have h_foo : True := True.intro
/// ```hermes
/// ensures: True
/// ```
pub fn unit_arg(_: ()) {}

/// ```hermes
/// ensures: True
/// ```
pub fn unit_ret() -> () {}
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ Behavior: Uses parameters such as `&&u32`, `&mut &u32`, and `&&mut u32`. Validat
"""

[test]
expected_status = "failure"
expected_status = "known_bug"
args = ["verify", "--allow-sorry"]

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
description = """
Purpose: Exercises end-to-end Lean verification integration evaluating `isValid` invariants.
Behavior: Uses `--verify` to trigger Lean analysis on the extracted logic. Confirms that purposefully faulty initialization states correctly drive Lean to trip the `Decidable` invariant logic, reporting "failed to synthesize" through Hermes.
Behavior: Confirms that purposefully faulty initialization states correctly drive Lean to trip the `Decidable` invariant logic, reporting "failed to synthesize" through Hermes.
"""

[test]
Expand Down
4 changes: 4 additions & 0 deletions tools/hermes/tests/fixtures/map_symlinked_file/hermes.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Purpose: Validates diagnostics resolution pointing to canonicalized symlinks.
Behavior: Provides Charon errors mapped to an original `untransformed.rs` target spanning behind a symlink. Ensures Hermes resolves and prints the logical/canonical code appropriately.
"""

# FIXME(#3089): It looks like this test *originally* correctly exercised symlink
# logic, but it doesn't anymore. We should fix this to ensure it actualy
# uses symlinks.

[test]
stderr_file = "expected.stderr"
args = ["verify", "--allow-sorry"]
Expand Down
Loading
Loading