Skip to content

Conversation

@joshlf
Copy link
Member

@joshlf joshlf commented Feb 4, 2026


⬇️ Download this PR

Branch

git fetch origin refs/heads/G8b674511787c67f5fdb20d28e10d9387316037ae && git checkout -b pr-G8b674511787c67f5fdb20d28e10d9387316037ae FETCH_HEAD

Checkout

git fetch origin refs/heads/G8b674511787c67f5fdb20d28e10d9387316037ae && git checkout FETCH_HEAD

Cherry Pick

git fetch origin refs/heads/G8b674511787c67f5fdb20d28e10d9387316037ae && git cherry-pick FETCH_HEAD

Pull

git pull origin refs/heads/G8b674511787c67f5fdb20d28e10d9387316037ae

Stacked PRs enabled by GHerrit.

gherrit-pr-id: G8b674511787c67f5fdb20d28e10d9387316037ae
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @joshlf, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request fundamentally changes how unsafe functions designated for Lean modeling are processed. By replacing their Rust bodies with an infinite loop, the system ensures that their behavior is defined purely by their formal specifications, moving away from potentially inconsistent 'safe shims'. This approach strengthens the soundness of the verification process. Additionally, the changes streamline the Lean code generation by separating concerns into distinct files and improve the integration with the Charon tool by explicitly marking model functions as opaque.

Highlights

  • Modeling Unsafe Functions as Noncomputable: Functions marked with #[lean model] that are unsafe will now have their Rust implementation replaced with loop {} in the shadow crate. This makes them diverge (noncomputable), ensuring their behavior is defined solely by their Lean specifications and enabling more robust formal verification.
  • Lean Code Generation Refactoring: The Lean code generation process has been refactored to separate UserProofs.lean and FunsExternal.lean. Model functions will now generate noncomputable def entries in FunsExternal.lean, using Classical.choose based on their desugared predicates and binders.
  • Charon Integration for Opaque Functions: The run_charon function now accepts a list of opaque_funcs. Model function names are collected during shadow crate creation and passed to Charon, allowing them to be treated as opaque during the translation to LLBC.
  • Enhanced Shadow Crate Creation: The shadow crate creation process (shadow.rs) has been updated to identify and collect the fully qualified names of model functions, which are then used in subsequent pipeline steps.
  • Mutable Reference Check for Models: A new check has been introduced to prevent functions marked as models from having mutable references in their signatures, as this is not supported by the current modeling approach.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • tools/hermes/src/desugar.rs
    • Added predicate: Option<String> and binders: Vec<String> fields to DesugaredSpec to store parsed Lean predicate logic and binders.
    • Modified desugar_spec to correctly extract and populate these new fields.
    • Changed parse_binders visibility from fn to pub fn.
  • tools/hermes/src/include/__hermes_std.rs
    • Replaced the body of pub unsafe fn read<T>(src: *const T) -> T with loop {} to make it noncomputable.
  • tools/hermes/src/orchestration.rs
    • Modified run_charon function signature to accept opaque_funcs: &[String] and pass them as --opaque arguments to the Charon command.
    • Renamed ALL_AENEAS_BACKENDS to _ALL_AENEAS_BACKENDS (prefixing with _ to mark as unused).
    • Added -split-files argument to the aeneas command.
  • tools/hermes/src/pipeline.rs
    • Updated create_shadow_crate call to receive the list of models.
    • Prepend crate name to collected model names and pass them as opaque_funcs to run_charon.
    • Refactored generate_lean_file to separate Lean code into UserProofs.lean and FunsExternal.lean.
    • FunsExternal.lean now generates noncomputable def for model functions, using Classical.choose based on the desugared predicate and binders.
    • Added a check to prevent models with mutable references.
  • tools/hermes/src/shadow.rs
    • Modified create_shadow_crate, sanitize_crate, and process_file_content functions to return Vec<String> containing the names of identified model functions.
    • Updated ShadowVisitor to collect model function names, including their module paths.
    • Changed the ShadowVisitor logic for #[lean model] functions: removed unsafe keyword and replaced the function body with loop {} (infinite loop) instead of the previous 'Safe Shim'.
    • Ensured #[allow(unused_variables)] is added to model functions.
    • Removed the model_requires logic from parse_model_specs as it's no longer used for generating the shim.
    • Updated test cases to reflect the new loop {} body for model functions.
  • tools/hermes/tests/cases/failure/model_mut_ref.rs
    • Added a new test file to specifically test a model function with a mutable reference, which is now explicitly disallowed.
Activity
  • The pull request is currently marked as [WIP], indicating ongoing development.
  • A gherrit-pr-id is present, suggesting integration with an internal review system.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the handling of unsafe functions marked as lean model. Instead of generating a Rust shim that panics, their bodies are now replaced with loop {} in a shadow crate. This change allows them to be modeled as noncomputable functions in Lean. The implementation involves updating the shadow crate generation, passing opaque function information to Charon, and generating noncomputable defs in a new FunsExternal.lean file. The changes are well-aligned with the goal of the PR. My review includes suggestions to address some code duplication and remove leftover development artifacts for better code clarity and maintainability.

Comment on lines +86 to +98
let (predicate, binders) = if let Some(ens) = &ensures_clause {
let (binders, logic) = parse_binders(ens)?;
let mut full = logic;
if !logic_lines.is_empty() {
for l in &logic_lines {
full.push_str("\n ");
full.push_str(l);
}
}
(Some(full), binders)
} else {
(None, Vec::new())
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This block of code duplicates the logic from lines 55-70 for parsing the ensures clause and concatenating logic lines. To improve maintainability and avoid redundancy, this logic should be computed once and the result reused.

Comment on lines +495 to +497
if !funs_external_content.is_empty() {
fs::write(dest.join("FunsExternal.lean"), funs_external_content)?;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The condition !funs_external_content.is_empty() will always evaluate to true because funs_external_content is initialized with import statements and namespace declarations. This results in an empty FunsExternal.lean file being created even when there are no model functions. It would be more precise to only create this file if there are actual models to write.

Suggested change
if !funs_external_content.is_empty() {
fs::write(dest.join("FunsExternal.lean"), funs_external_content)?;
}
if functions.iter().any(|f| f.is_model) {
fs::write(dest.join("FunsExternal.lean"), funs_external_content)?;
}

Comment on lines +154 to +163
// mod charon { pub use charon_macros::opaque; }
// We need `charon_macros` to exist or be faked.
// Actually, since we rewrite the crate, we can just define a dummy `opaque` attribute logic?
// Rustc allows custom attributes if they are mapped to a tool or via `register_tool` (nightly).
// For stable, we might need a dummy macro or just `allow` it?
// But `#[charon::opaque]` looks like a path attribute.
// Let's define: `pub mod charon { pub use crate::hermes_std::opaque; }`
// and in `hermes_std` define `pub use ...`?
// Simpler: define `mod charon` right here which exports a dummy `opaque` attribute macro?
// Attributes must be macros.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These comments appear to be development notes or thoughts about implementation details. They should be removed to keep the code clean and focused on the implementation itself.

Comment on lines +338 to +345
// Debugging loop
/*
for attr in attrs {
if attr.path().is_ident("doc") {
println!("Found doc attr: {:?}", attr);
}
}
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This commented-out debugging loop should be removed from the final code.

@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 92.02%. Comparing base (a1c0b5f) to head (0c4aad9).

Additional details and impacted files
@@                            Coverage Diff                             @@
##           G0b9216c6738c722e3424be5ee5e085157b5813f9    #2978   +/-   ##
==========================================================================
  Coverage                                      92.02%   92.02%           
==========================================================================
  Files                                             19       19           
  Lines                                           6029     6029           
==========================================================================
  Hits                                            5548     5548           
  Misses                                           481      481           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants