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.
Inductive verification for function contracts as conceived by #2809 places a
kani::Arbitrarybound on all check functions which means that contracts for functions with return types that do not implementkani:Arbitrarycan no longer be#[kani::proof_for_contract(...)]checked.Previously a
kani::Arbitrarybound 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 nokani::Arbitraryimplementation exists, for instance if the returned type was third-party. Inductive verification uses of a verified stub on recursive re-entry, entailing thekani::Arbitraryconstraint 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.