Skip to content

Force-load the kani crate so no_std crates work out of the box - #4682

Open
tautschnig wants to merge 1 commit into
model-checking:mainfrom
tautschnig:fix-nostd-extern-kani
Open

Force-load the kani crate so no_std crates work out of the box#4682
tautschnig wants to merge 1 commit into
model-checking:mainfrom
tautschnig:fix-nostd-extern-kani

Conversation

@tautschnig

Copy link
Copy Markdown
Member

Description

Kani passes --extern kani, which makes the kani crate resolvable but does not load it unless the code under verification references it. #[no_std] crates never link Kani's std (which is what otherwise pulls kani in transitively), so verifying them fails with "Failed to detect Kani functions" unless the user manually adds extern crate kani to their crate root — the workaround suggested by the error message introduced for #3906.

This PR uses the force extern modifier (unstable, like the noprelude modifier Kani already relies on) so the kani crate is always loaded. With this:

  • a no_std crate with #[cfg(kani)] #[kani::proof] harnesses and no kani import verifies out of the box (kani:: paths resolve via the forced extern), and
  • kani autoharness works on unmodified no_std crates.

Context: while evaluating autoharness on the top-100 crates.io crates, roughly a third of the corpus is no_std and hit this error; each needed a source modification to proceed.

One pre-existing interaction is unchanged: crates that deny(unused_crate_dependencies) already fail on Kani's injected noprelude:std extern, with or without this change (verified against main). Fixing that lint interaction is a separate work item.

Testing

Updated tests/cargo-ui/no-std-no-kani from expecting the error message to expecting successful verification of a no_std harness that uses kani::any() without any extern crate kani. Full cargo-ui suite passes (29 tests).

Manually verified: cargo kani autoharness on the unmodified cfg-if crate (previously failed) now runs; deny(unused_crate_dependencies) behavior is unchanged vs. main.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.

Copilot AI review requested due to automatic review settings July 28, 2026 11:08
@tautschnig
tautschnig requested a review from a team as a code owner July 28, 2026 11:08
@github-actions github-actions Bot added Z-EndToEndBenchCI Tag a PR to run benchmark CI Z-CompilerBenchCI Tag a PR to run benchmark CI labels Jul 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Kani driver to force-load the kani crate via --extern force:kani, ensuring #[no_std] crates don’t fail verification due to missing Kani functions when the user code never explicitly references/imports kani.

Changes:

  • Pass --extern force:kani when compiling single files so the kani crate is loaded even if unused by the target crate.
  • Update the cargo-ui no-std-no-kani test to verify a #[no_std] harness can call kani::any() without extern crate kani.
  • Adjust the expected output for that test from an error to successful verification.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tests/cargo-ui/no-std-no-kani/src/lib.rs Updates the test crate to include a #[cfg(kani)] proof harness using kani::any() without importing kani.
tests/cargo-ui/no-std-no-kani/expected Changes the UI expectation from the “Failed to detect Kani functions” error to a successful verification result.
kani-driver/src/call_single_file.rs Switches the injected --extern kani to --extern force:kani so kani is loaded even when unused, fixing no_std out-of-the-box verification.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +26 to +30
// Use the `force` modifier so that the `kani` crate is resolved even if the code
// under verification never references it. `#[no_std]` crates do not link Kani's
// `std` (which would otherwise pull in `kani`), so without `force` the Kani
// library and its functions would be missing entirely, c.f.
// https://github.com/model-checking/kani/issues/3906.
Kani passed '--extern kani', which makes the kani crate resolvable but does
not load it unless the code under verification references it. Crates using
#[no_std] never link Kani's std (which is what otherwise pulls in kani), so
verifying them failed with 'Failed to detect Kani functions' unless the user
manually added 'extern crate kani' to their crate root.

Use the (unstable) 'force' extern modifier -- alongside the already-used
'noprelude' modifier -- so the kani crate is always loaded. A no_std crate
with proof harnesses and no kani import now verifies out of the box, and
'kani autoharness' works on unmodified no_std crates (about a third of the
top-100 crates.io crates).

The no-std-no-kani test now expects success rather than the old error
message. Note that a pre-existing interaction remains for crates that
deny(unused_crate_dependencies): Kani's injected 'noprelude:std' extern trips
that lint with or without this change.

This addresses the root cause behind the confusing error message reported in model-checking#3906.

Co-authored-by: Kiro <kiro-agent@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Z-CompilerBenchCI Tag a PR to run benchmark CI Z-EndToEndBenchCI Tag a PR to run benchmark CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants