|
| 1 | +- **Feature Name:** Unstable APIs (`unstable-api`) |
| 2 | +- **RFC Tracking Issue**: <https://github.com/model-checking/kani/issues/2279> |
| 3 | +- **RFC PR:** <https://github.com/model-checking/kani/pull/2281> |
| 4 | +- **Status:** Under Review |
| 5 | +- **Version:** 0 |
| 6 | + |
| 7 | +------------------- |
| 8 | + |
| 9 | +## Summary |
| 10 | + |
| 11 | +Provide a standard option for users to enable experimental APIs and features in Kani, |
| 12 | +and ensure that those APIs are off by default. |
| 13 | + |
| 14 | +## User Impact |
| 15 | + |
| 16 | +Add an opt-in model for users to try experimental APIs. |
| 17 | +The goal is to enable users to try features that aren't stable yet, |
| 18 | +which allow us to get valuable feedback during the development of new features and APIs. |
| 19 | + |
| 20 | +The opt-in model empowers the users to control when some instability is acceptable, |
| 21 | +which makes Kani UX more consistent and safe. |
| 22 | + |
| 23 | +Currently, each new unstable feature will introduce a new switch, some of them will look like `--enable-<feature>`, |
| 24 | +while others will be a plain switch which allows further feature configuration `--<feature-config>=[value]`. |
| 25 | +For example, we today have the following unstable switches `--enable-stubbing`, `--concrete-playback`, `--gen-c`. |
| 26 | +In all cases, users are still required to provide the additional `--enable-unstable` option. |
| 27 | +Some unstable features are included in the `--help` section, and only a few mention the requirement |
| 28 | +to include `--enable-unstable`. There is no way to list all unstable features. |
| 29 | +The transition to stable switches is also ad-hoc. |
| 30 | + |
| 31 | +In order to reduce friction, we will also standardize how users opt-in to any Kani unstable feature. |
| 32 | +We will use similar syntax to the one used by the Rust compiler and Cargo. |
| 33 | +As part of this work, we will also deprecate and remove `--enable-unstable` option. |
| 34 | + |
| 35 | +Note that although Kani is still on v0, which means that everything is somewhat unstable, |
| 36 | +this allow us to set different bars when it comes to what kind of changes is expected, |
| 37 | +as well as what kind of support we will provide for a feature. |
| 38 | + |
| 39 | +## User Experience |
| 40 | + |
| 41 | +Users will have to invoke Kani with: |
| 42 | +``` |
| 43 | +-Z <feature_identifier> |
| 44 | +``` |
| 45 | +in order to enable any unstable feature in Kani, including unstable APIs in the Kani library. |
| 46 | +For unstable command line options, we will add `-Z unstable-options`, similar to the Rust compiler. |
| 47 | +E.g.: |
| 48 | +``` |
| 49 | +-Z unstable-options --concrete-playback=print |
| 50 | +``` |
| 51 | + |
| 52 | +Users will also be able to enable unstable features in their `Cargo.toml` in the `unstable` table |
| 53 | +under `kani` table. E.g: |
| 54 | +```toml |
| 55 | +[package.metadata.kani.unstable] |
| 56 | +unstable-options = true |
| 57 | + |
| 58 | +[workspace.metadata.kani] |
| 59 | +flags = { concrete-playback = true } |
| 60 | +unstable = { unstable-options = true } |
| 61 | +``` |
| 62 | + |
| 63 | +In order to mark an API as unstable, we will add the following attribute to the APIs marked as unstable: |
| 64 | + |
| 65 | +```rust |
| 66 | +#[kani::unstable(feature="<IDENTIFIER>", issue="<TRACKING_ISSUE_NUMBER>", reason="<OPTIONAL_DESCRIPTION>")] |
| 67 | +pub fn unstable_api() {} |
| 68 | +``` |
| 69 | + |
| 70 | +This is similar to the interface used by [the standard library](https://rustc-dev-guide.rust-lang.org/stability.html#unstable). |
| 71 | + |
| 72 | +If the user tries to use an unstable feature in Kani without explicitly enabling it, |
| 73 | +Kani will trigger an error. For unstable APIs, the error will be triggered during the crate |
| 74 | +compilation. |
| 75 | + |
| 76 | +## Detailed Design |
| 77 | + |
| 78 | +We will add the `-Z` option to both `kani-driver` and `kani-compiler`. |
| 79 | +Kani driver will pass the information to the compiler. |
| 80 | + |
| 81 | +For unstable APIs, the compiler will check if any reachable function uses an unstable feature that was not enabled. |
| 82 | +If that is the case, the compiler will trigger a compilation error. |
| 83 | + |
| 84 | +We will also change the compiler to only generate code for harnesses that match the harness filter. |
| 85 | +The filter is already passed to the compiler, but it is currently only used for stubbing. |
| 86 | + |
| 87 | +### API Stabilization |
| 88 | + |
| 89 | +Once an API has been stabilized, we will remove the `unstable` attributes from the given API. |
| 90 | +If the user tries to enable a feature that was already stabilized, |
| 91 | +Kani will print a warning stating that the feature has been stabilized. |
| 92 | + |
| 93 | +### API Removal |
| 94 | + |
| 95 | +If we decide to remove an API that is marked as unstable, we should follow a regular deprecation |
| 96 | +path (using `#[deprecated]` attribute), and keep the `unstable` flag + attributes, until we are |
| 97 | +ready to remove the feature completely. |
| 98 | + |
| 99 | +## Rational and Alternatives |
| 100 | + |
| 101 | +For this RFC, the suggestion is to only enable experimental features globally for simplicity of use and implementation. |
| 102 | + |
| 103 | +For now, we will trigger a compilation error if an unstable API is reachable from a user crate |
| 104 | +unless if the user opts in for the unstable feature. |
| 105 | + |
| 106 | +We could allow users to specify experimental features on a per-harness basis, |
| 107 | +but it could be tricky to make it clear to the user which harness may be affected by which feature. |
| 108 | +The extra granularity would also be painful when we decide a feature is no longer experimental, |
| 109 | +whether it is stabilized or removed. |
| 110 | +In those cases, users would have to edit each harness that enables the affected feature. |
| 111 | + |
| 112 | +## Open questions |
| 113 | + |
| 114 | +- Should we also add a `stable` attribute that documents when an API was stabilized? |
| 115 | + |
| 116 | +## Future possibilities |
| 117 | + |
| 118 | +- Delay the error due to the usage of a unstable API, and only fail at runtime if the API is reachable. |
| 119 | +- Allow users to enable unstable features on a per-harness basis. |
0 commit comments