|
| 1 | +- Feature Name: feature-deprecation |
| 2 | +- Start Date: 2023-09-09 |
| 3 | +- RFC PR: [rust-lang/rfcs#3416](https://github.com/rust-lang/rfcs/pull/3416) |
| 4 | +- Rust Issue: |
| 5 | + [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) |
| 6 | + |
| 7 | +# Summary |
| 8 | + |
| 9 | +[summary]: #summary |
| 10 | + |
| 11 | +This RFC describes a new key under `features` in `Cargo.toml` to indicate that a |
| 12 | +feature is deprecated. |
| 13 | + |
| 14 | +Please see the parent meta RFC for background information: [`feature-metadata`]. |
| 15 | + |
| 16 | +# Motivation |
| 17 | + |
| 18 | +[motivation]: #motivation |
| 19 | + |
| 20 | +Cargo features are widely used and typically have lifecycles the same as other |
| 21 | +API components. There is not currently a way to indicate that a feature is |
| 22 | +intended for removal and warn about it: This RFC proposes a `deprecated` key |
| 23 | +that shows this information. |
| 24 | + |
| 25 | +# Guide-level explanation |
| 26 | + |
| 27 | +[guide-level-explanation]: #guide-level-explanation |
| 28 | + |
| 29 | +A new `deprecated` key will be allowed for features, defaulting to `false` if |
| 30 | +not specified. If specified, the value can be either a boolean, a string, or an |
| 31 | +object with `since` and/or `note` keys. Cargo will warn downstream crates using |
| 32 | +this feature. |
| 33 | + |
| 34 | +```toml |
| 35 | +[features] |
| 36 | +foo = { enables = [], deprecated = true } |
| 37 | +foo = { enables = [], deprecated = "this works as a note" } |
| 38 | +bar = { enables = [], deprecated = { since = "1.2.3", note = "don't use this!" } } |
| 39 | +``` |
| 40 | + |
| 41 | +See [`feature-metadata`] for information about `enables`. |
| 42 | + |
| 43 | +# Reference-level explanation |
| 44 | + |
| 45 | +[reference-level-explanation]: #reference-level-explanation |
| 46 | + |
| 47 | +`deprecated` should be thought of as the equivalent of the [`deprecated`] |
| 48 | +attribute in Rust source. The value can be a boolean, string, or an object with |
| 49 | +`since` or `note` keys. Schema rules are as follows: |
| 50 | + |
| 51 | +- If a boolean value, `false` indicates not deprecated and `true` indicates |
| 52 | + deprecated |
| 53 | +- If an object, the keys `since` and/or `note` can be specified |
| 54 | +- An empty object is not allowed to avoid ambiguity `foo = { deprecated = {} }` |
| 55 | +- A string `foo = { deprecated = "my msg" }` will be equivalent to if that |
| 56 | + string was specified in the `note` field: |
| 57 | + `foo = { deprecated = { note = "my msg" } }` |
| 58 | +- If not specified, the default is `false` |
| 59 | + |
| 60 | +If a downstream crate attempts to use a feature marked `deprecated`, Cargo |
| 61 | +should produce a warning that contains the `note`. This warning should not be |
| 62 | +emitted for crates that reexport the feature under a feature also marked |
| 63 | +deprecated. For example: crate `foo` exports feature `phooey`, and crate `bar` |
| 64 | +exports feature `barred = ["foo/phooey"]`. If `foo` markes `bar` as deprecated, |
| 65 | +running any cargo action on `bar` will emit a warning unless `barred` is also |
| 66 | +marked `deprecated. |
| 67 | + |
| 68 | +Accessing this information will require access to the manifest as it will not be |
| 69 | +in the index. |
| 70 | + |
| 71 | +## A note on `since` |
| 72 | + |
| 73 | +The exact behavior of the `since` key is not provided in this RFC as there are |
| 74 | +decisions related to resolution that need to be made. The generally accepted |
| 75 | +concept is that there should be a warning if a deprecated feature is used _and_ |
| 76 | +there is something actionable to resolve this issue for all downstream crates - |
| 77 | +but the details of how best to do this are not yet clear. Please see |
| 78 | +[discussion on since]. |
| 79 | + |
| 80 | +If the exact behavior of `since` does not reach consensus before `deprecated` is |
| 81 | +nearing stabilization, this key can stabilized separately or dropped entirely. |
| 82 | + |
| 83 | +## Index changes |
| 84 | + |
| 85 | +[index changes]: #index-changes |
| 86 | + |
| 87 | +The infromation provided by `deprecated` needs to be stored in the index, and |
| 88 | +will be stored under a `features3` key. Older versions of Cargo will ignore this |
| 89 | +key, newer Cargo would be able to merge `features`, `features2`, and |
| 90 | +`features3`. `features3` should mirror the most complete syntax of the relevant |
| 91 | +keys from the `[features]` table, i.e.: |
| 92 | + |
| 93 | +```json5 |
| 94 | +"features3": { |
| 95 | + "bar": { |
| 96 | + deprecated = { since = "1.2.3", note = "don't use this" } |
| 97 | + } |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +In order to conserve index space, default keys should be omitted. `Cargo` should |
| 102 | +ignore unrecognized keys within a feature, to allow for future additions without |
| 103 | +needing a new `features` section. |
| 104 | + |
| 105 | +# Drawbacks |
| 106 | + |
| 107 | +[drawbacks]: #drawbacks |
| 108 | + |
| 109 | +- Added complexity to Cargo. Parsing is trivial, but exact implementation |
| 110 | + details do add test surface area |
| 111 | +- There is no way to structure features in a way that they are split into |
| 112 | + sections or have a user-specified layout, unlike with the `document-features` |
| 113 | + crate. |
| 114 | + |
| 115 | +# Rationale and alternatives |
| 116 | + |
| 117 | +[rationale-and-alternatives]: #rationale-and-alternatives |
| 118 | + |
| 119 | +WIP |
| 120 | + |
| 121 | +# Prior art |
| 122 | + |
| 123 | +[prior-art]: #prior-art |
| 124 | + |
| 125 | +WIP |
| 126 | + |
| 127 | +# Unresolved questions |
| 128 | + |
| 129 | +[unresolved-questions]: #unresolved-questions |
| 130 | + |
| 131 | +- How should `since` work with the `deprecated` key? See |
| 132 | + [a note on `since`](#a-note-on-since) for further information. |
| 133 | + |
| 134 | +# Future possibilities |
| 135 | + |
| 136 | +[future-possibilities]: #future-possibilities |
| 137 | + |
| 138 | +- Somehow inform users if they are using to-be-deprecated features, i.e., |
| 139 | + deprecated `since` is set but is later than the current dependancy version. |
| 140 | +- Via the `manifest-lint` RFC, a user could specify that deprecated crates |
| 141 | + should be denied. This would, however, be blocked by [cargo #12335]. |
| 142 | +- A `stable` field can be set false to indicate API-unstable or nightly-only |
| 143 | + features (somethign such as `stable = 3.2` could be used to indicate when a |
| 144 | + feature was stabilized). See also: |
| 145 | + <https://github.com/rust-lang/cargo/issues/10882> |
| 146 | +- A `rust-version` field that could indicate e.g. `rust-version = "nightly"` or |
| 147 | + `rust-version = "1.65"` to specify a MSRV for that feature. See: |
| 148 | + <https://github.com/rust-lang/rfcs/pull/3416#discussion_r1174478461> |
| 149 | +- `cargo add` can show the `deprecated` summary with the listed features. |
| 150 | +- `deprecated` could take a `suggestion` key that indicates features have moved |
| 151 | + to a different name (as with the [`deprecated-suggestions`] feature) |
| 152 | + |
| 153 | +[cargo #12335]: https://github.com/rust-lang/cargo/issues/12235 |
| 154 | +[cargo #10882]: https://github.com/rust-lang/cargo/issues/10882 |
| 155 | +[`cargo-info`]: https://github.com/rust-lang/cargo/issues/948 |
| 156 | +[`deprecated`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute |
| 157 | +[`deprecated-suggestions`]: https://github.com/rust-lang/rust/issues/94785 |
| 158 | +[discussion on since]: https://github.com/rust-lang/rfcs/pull/3416#discussion_r1172895497 |
| 159 | +[`public_private_dependencies`]: https://rust-lang.github.io/rfcs/1977-public-private-dependencies.html |
| 160 | +[`rustdoc-cargo-configuration`]: https://github.com/rust-lang/rfcs/pull/3421 |
| 161 | +[`tokio`]: https://docs.rs/crate/tokio/latest/features |
| 162 | +[visibility attribute]: https://ant.apache.org/ivy/history/latest-milestone/ivyfile/conf.html |
| 163 | +[`feature-metadata`]: https://github.com/rust-lang/rfcs/pull/3416 |
0 commit comments