Skip to content

Treat optional hooks as optional in the missing-function check - #4799

Merged
feliperodri merged 1 commit into
model-checking:mainfrom
srivatsansamraj:kani-optional-hooks
Sep 23, 2026
Merged

feliperodri merged 1 commit into
model-checking:mainfrom
srivatsansamraj:kani-optional-hooks

Conversation

@srivatsansamraj

@srivatsansamraj srivatsansamraj commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Description

validate_kani_functions reports a missing Kani function unless it is an optional model:

} else if !matches!(func, KaniFunction::Model(model) if model.is_optional()) {

is_optional exists only on KaniModel, so that arm can never match a hook.
SliceValidityAssume is a hook and is only defined in the kani library, not in
core::kani, so a whole-library run logs, once per crate and at ERROR level:

ERROR kani_compiler::kani_middle::kani_functions Missing kani function, func=Hook(SliceValidityAssume)
ERROR kani_compiler::kani_middle::kani_functions Failed to find `1` Kani functions

for a condition that is not fatal.

This gives KaniHook the same is_optional method, lets KaniFunction delegate to
whichever variant it holds, and reduces the check to !func.is_optional().

Context

Absence is already handled safely. The hook implementations are a static table keyed by
KaniHook in overrides/hooks.rs, so the implementation is always present; what can be
missing is a marked function in the crate being compiled. If nothing calls
kani::slice_validity_assume, there is nothing to lower.

The doc comment on KaniHook::is_optional follows the wording already on
KaniModel::is_optional, since the reason is the same: defined in kani, absent from
core::kani.

Reported from the verify-rust-std toolchain bump
(model-checking/verify-rust-std#687), where the message is emitted 47,480 times in a
single run and obscured the real blocker.

Resolved issues

Resolves #4795

Testing

cargo build-dev, cargo fmt --check, and cargo clippy --workspace --tests -- -D warnings
with and without RUSTFLAGS="--cfg=kani_sysroot".

No unit test was added: kani_functions.rs has no test module, and the change is a
two-arm delegation over an enum the compiler already checks exhaustively.

Reproduced on a whole-library verify-std run on nightly-2026-08-21. Before the change, a run stopped after 11 crates had printed 412,399 lines, 411,806 of them these two messages. With it, a complete run over 32 crate compilations printed 85,262 lines and neither message. That run needed a local workaround for #4794 (since fixed by #4820) and the NonNull fixes in #4801.

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

`validate_kani_functions` exempts a missing Kani function only when it is an
optional model, but `is_optional` is defined on `KaniModel` alone, so the match
arm can never cover a hook. `SliceValidityAssume` is a hook and is only defined
in the `kani` library, not in `core::kani`, so whole-library runs log a
per-crate `ERROR` for a condition that is not fatal.

Give `KaniHook` the same method, let `KaniFunction` delegate to whichever
variant it holds, and reduce the check to `!func.is_optional()`.

Resolves model-checking#4795
@srivatsansamraj
srivatsansamraj requested review from a team as code owners September 16, 2026 22:49
@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 Sep 16, 2026
@feliperodri
feliperodri requested a balanced review from Copilot September 17, 2026 01:46

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.

🟢 Approval recommended

The focused change correctly suppresses misleading errors while preserving validation for required functions.

Pull request overview

Updates Kani’s missing-function validation to recognize optional hooks.

Changes:

  • Marks SliceValidityAssume as optional.
  • Delegates optionality checks through KaniFunction.
File summaries
File Description
kani-compiler/src/kani_middle/kani_functions.rs Adds hook optionality and simplifies validation.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@srivatsansamraj

Copy link
Copy Markdown
Contributor Author

Reproduced, and the change is verified over the whole library. The "I have not reproduced the original log output" note in the description is out of date.

Before. A run stopped partway, having compiled 11 crates:

total output lines 412,399
Missing kani function, func=Hook(SliceValidityAssume) 205,903
Failed to find `1` Kani functions 205,903

411,806 of 412,399 lines, 99.9%, for a condition that is not fatal. The cost is not hypothetical: that run was killed on the assumption it had failed, because the console showed nothing else. It was compiling core normally at the time.

After. With this change, a complete run over 32 crate compilations:

total output lines 85,262
either message 0

Exit 0, kani-list.json written, 26,975 of 45,796 functions selected across 23 crates.

Three things had to be out of the way to get that far, none of them this PR, listed so the result is not read as a clean-tree run:

The last two are unfiled. I will open them separately with a reproduction.

@feliperodri feliperodri self-assigned this Sep 17, 2026

@feliperodri feliperodri left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Approving.

I hit this myself without looking for it: a std autoharness run of mine logged 1,278 of each message in a 3,317-line log, roughly 77% of the output, at ERROR level, for something non-fatal. Your numbers match what I saw.

The fix is in the right place. slice_validity_assume's only callers are any_slice_ref_unbounded, any_slice_mut_unbounded and any_vec_unbounded, all three already in KaniModel::is_optional() — the hook was simply missed when that list was written. If it is absent its callers are too, and the library body is unreachable!(), so a genuinely missed lowering still fails loudly rather than silently.

Two non-blocking asks: fold your reproduction comment into the description, which still says you have not reproduced the output; and file the NonNull pattern-type and RAW_PTR_FROM_BOX findings from that comment separately — the second looks related to #4800.

@feliperodri
feliperodri added this pull request to the merge queue Sep 22, 2026
Merged via the queue into model-checking:main with commit 92172e3 Sep 23, 2026
33 checks passed
@srivatsansamraj

Copy link
Copy Markdown
Contributor Author

Thanks, folded the reproduction into the description; both findings are filed as #4800 and fixed together in #4801.

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.

Misleading non-fatal "Failed to find Kani functions" ERROR for optional hooks (SliceValidityAssume) during whole-library runs

3 participants