Treat optional hooks as optional in the missing-function check - #4799
Conversation
`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
There was a problem hiding this comment.
🟢 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
SliceValidityAssumeas 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.
|
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:
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 After. With this change, a complete run over 32 crate compilations:
Exit 0, 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
left a comment
There was a problem hiding this comment.
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.
Description
validate_kani_functionsreports a missing Kani function unless it is an optional model:is_optionalexists only onKaniModel, so that arm can never match a hook.SliceValidityAssumeis a hook and is only defined in thekanilibrary, not incore::kani, so a whole-library run logs, once per crate and atERRORlevel:for a condition that is not fatal.
This gives
KaniHookthe sameis_optionalmethod, letsKaniFunctiondelegate towhichever 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
KaniHookinoverrides/hooks.rs, so the implementation is always present; what can bemissing 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_optionalfollows the wording already onKaniModel::is_optional, since the reason is the same: defined inkani, absent fromcore::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, andcargo clippy --workspace --tests -- -D warningswith and without
RUSTFLAGS="--cfg=kani_sysroot".No unit test was added:
kani_functions.rshas no test module, and the change is atwo-arm delegation over an enum the compiler already checks exhaustively.
Reproduced on a whole-library
verify-stdrun 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 theNonNullfixes 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.