kani
kani copied to clipboard
Improvements needed for the 'kani' library
any, Arbitrary and Invariant
- [ ] The current implementation of
Invariantis basically inviting undefined behavior. For instance, an invariant like "this enum must match one of its variants" is something the rust compiler could replace with justtrue. (It sort of already does: if you do this with pattern matching, it recognizes the wildcard branch as dead code, and Kani helpfully codegen's dead code asassert(false)!) - [ ] The current implementation of
Arbitraryoffers essentially nothing useful. For instance, implementingArbitraryforMyTypedoes not mean you can useany()forOption<MyType>because the implication instances forOptionare onInvariant - [ ] We could move some of these from
InvarianttoArbitrarybut that starts to eliminate the usefulness ofInvariant, and... (next item) - [ ] In the long term, we DO want
Invariant, it's just that we'd want the compiler to synthesize the basic ones for types. (All the invariants that are undefined behavior are the ones we should be able to implement automatically because they're the Rust invariants for types.) - [ ] We should make
any_rawprivate, users probably shouldn't be using it, and it's mostly UB. It can be mimic'd by gettinganybytes and thentransmute, with all the obvious UB implications.
any_vec, slices
I don't believe the current API is the one we should consider stabilized.
- [ ]
any_slicereturns a fairly complicatedAnySlicetype, because it needs something to own the data. Thing is, the standard library already has a type for that...Vec. I'm not sure why we don't just haveany_vecalone here. - [ ] We should probably mark all
rawfunctions as private. - [ ] IMO
any_slice_of_arrayshould beany_subslice - [ ] I'm not sure why
any_sliceandany_vecpass in the bound as a const generic. Seems like it'd be best if it were an ordinary parameter. It makes these hard to use. (I didn't look into the implementations though, so could easily be a reason we have to unfortunately) - [ ] These implementations should be exported at the top level. i.e.
kani::any_vecnotkani::vec::any_vec - [ ] We should add an
any_stringimplementation.
Assertions
- [ ]
nondetshould be removed or at leastdoc(hidden) - [ ]
panicshould probably be at leastdoc(hidden). Not something we expect customers to know about. - [ ]
assertshould be renamedcheck - [ ]
expect_failshould be replaced withcover#1197
I tried adding any_string but I either bumped into really poor performance or linking issues. Hopefully we can get back to it once we fix the std lib linking.
I'm not sure why any_slice and any_vec pass in the bound as a const generic. Seems like it'd be best if it were an ordinary parameter. It makes these hard to use. (I didn't look into the implementations though, so could easily be a reason we have to unfortunately)
Generally agreed. I think we will have to move to this direction anyway due to certain protests using this.
Although, one concern is that x : [T;N] = any() has had better performance than the ones I tested with. This is especially true if the bounds are dynamically computed but in a way where there is a clear upper bound.
As discussed offline, regarding the first topic, we will do the following:
- [x] Deprecate
Invarianttrait andimpl Arbitrary for Invariantfor now (pending on @YoshikiTakashima potential use case). - [x] Convert all our implementations of
InvarianttoArbitrary. - [x] Change
any_vecto also take anArbitrary. - [x] We'll make
any_rawprivate for now.