-
Notifications
You must be signed in to change notification settings - Fork 135
Description
Inductive verification for function contracts as conceived by #2809 places a kani::Arbitrary bound on all check functions which means that contracts for functions with return types that do not implement kani:Arbitrary can no longer be #[kani::proof_for_contract(...)] checked.
Previously a kani::Arbitrary bound was only required if the contract was to be used as a verified stub #[kani::stub_verified(...)]. This would allow a user to check contracts for functions that return types for which no kani::Arbitrary implementation exists, for instance if the returned type was third-party. Inductive verification uses of a verified stub on recursive re-entry, entailing the kani::Arbitrary constraint on checks also and disallowing this use case.
The additional constraint applies to both recursive and non-recursive functions, because the procedural macro responsible for generating the check and replace functions cannot know whether a function is recursive. Mutually recursive functions have the recursive call in a nested function call whereas a procedural macro can only inspect the contents of its own body and thus not discover nested recursive calls.
To allow this use case Kani should allow users to opt-out of inductive verification on a per-function basis. For instance via a #[kani::no_induction] macro. This could potentially make verification of such functions more expensive if they use recursion, a risk the user would be explicitly opting-in to.
Alternatively inductive verification could be opt-in or it could be heuristically enabled if a non-mutual recursive call is detected and users could also opt-in explicitly for mutually recursive functions.