|
| 1 | +- Feature Name: feature-metadata |
| 2 | +- Start Date: 2023-04-14 |
| 3 | +- RFC PR: [rust-lang/rfcs#3416](https://github.com/rust-lang/rfcs/pull/3416) |
| 4 | +- Rust Issue: |
| 5 | + [rust-lang/cargo#13576](https://github.com/rust-lang/cargo/issues/13576) |
| 6 | + |
| 7 | +# Summary |
| 8 | + |
| 9 | +[summary]: #summary |
| 10 | + |
| 11 | +This RFC adds a "detailed" feature definition: |
| 12 | +```toml |
| 13 | +[features] |
| 14 | +# same as `foo = []` |
| 15 | +foo = { enables = [] } |
| 16 | +``` |
| 17 | + |
| 18 | +This is to unblock the following RFCs: |
| 19 | + |
| 20 | +- [Cargo feature descriptions](https://github.com/rust-lang/rfcs/pull/3485) |
| 21 | +- [Cargo feature deprecation](https://github.com/rust-lang/rfcs/pull/3486) |
| 22 | +- [Cargo feature visibility](https://github.com/rust-lang/rfcs/pull/3487) |
| 23 | + |
| 24 | +# Motivation |
| 25 | + |
| 26 | +[motivation]: #motivation |
| 27 | + |
| 28 | +Features are widely used as a way to do things like reduce dependency count, |
| 29 | +gate `std` or `alloc`-dependent parts of code, or hide unstable API. Use is so |
| 30 | +common that many larger crates wind up with tens of feature gates, such as |
| 31 | +[`tokio`] with 24. Despite being a first class component of crate structure, |
| 32 | +there are some limitations that don't have elegant solutions: |
| 33 | + |
| 34 | +- Documentation is difficult, often requiring library authors to manually manage |
| 35 | + a table of descriptions |
| 36 | +- There is no way to deprecate old features, as a way to help crates maintain |
| 37 | + semvar compliance |
| 38 | +- Features cannot be hidden from use in any way |
| 39 | + |
| 40 | +This RFC proposes a plan that add that information to `Cargo.toml`, solving |
| 41 | +these problems. |
| 42 | + |
| 43 | +# Guide-level explanation |
| 44 | + |
| 45 | +[guide-level-explanation]: #guide-level-explanation |
| 46 | + |
| 47 | +Usage is simple: features will be able to be specified as a table, instead of |
| 48 | +just a dependency array. This sample section of `Cargo.toml` shows new |
| 49 | +possibilities: |
| 50 | + |
| 51 | +```toml |
| 52 | +[features] |
| 53 | +# Current configuration will continue to work |
| 54 | +foo = [] |
| 55 | +# New configurations |
| 56 | +bar = { enables = ["foo"], doc = "simple docstring here"} |
| 57 | +baz = { enables = ["foo"], public = false} |
| 58 | +qux = { enables = [], deprecated = true } |
| 59 | +quux = { enables = [], deprecated = { since = "1.2.3", note = "don't use this!" } } |
| 60 | + |
| 61 | +# Features can also be full tables if descriptions are longer |
| 62 | +[features.corge] |
| 63 | +enables = ["bar", "baz"] |
| 64 | +doc = """ |
| 65 | +# corge |
| 66 | +
|
| 67 | +This could be a longer description of this feature |
| 68 | +""" |
| 69 | +``` |
| 70 | + |
| 71 | +The `enables` key is synonymous with the existing array, describing what other |
| 72 | +features are enabled by a given feature. For example, |
| 73 | +`foo = ["dep:serde", "otherfeat"]` will be identical to |
| 74 | +`foo = { enables = ["dep:serde", "otherfeat"] }` |
| 75 | + |
| 76 | +All other keys are described in their individual RFCs. |
| 77 | + |
| 78 | +## General Implementation & Usage |
| 79 | + |
| 80 | +Use cases for these new keys will likely develop with time, |
| 81 | +but one of the simplest applications is for information output with `cargo |
| 82 | +add`: |
| 83 | + |
| 84 | +```text |
| 85 | +crab@rust foobar % cargo add regex |
| 86 | + Updating crates.io index |
| 87 | + Adding regex v1.7.3 to dependencies. |
| 88 | + Features: |
| 89 | + + perf Enables all performance related features |
| 90 | + + perf-dfa Enables the use of a lazy DFA for matching |
| 91 | + + perf-inline Enables the use of aggressive inlining inside |
| 92 | + match routines |
| 93 | + + perf-literal Enables the use of literal optimizations for |
| 94 | + speeding up matches |
| 95 | + + std When enabled, this will cause regex to use the |
| 96 | + standard library |
| 97 | + + unicode Enables all Unicode features |
| 98 | + - deprecated (D) Not a real feature, but it could be |
| 99 | +
|
| 100 | + Updating crates.io index |
| 101 | +``` |
| 102 | + |
| 103 | +Features like `aho-corasick`, `memchr`, or `use_std` would likely be |
| 104 | +`public = false` since they aren't listed on the crate landing page. |
| 105 | + |
| 106 | +# Reference-level explanation |
| 107 | + |
| 108 | +[reference-level-explanation]: #reference-level-explanation |
| 109 | + |
| 110 | +`enables` will take the place of the feature dependency array that currently |
| 111 | +exists. Semantics will remain unchanged. |
| 112 | + |
| 113 | +This is a required key. If there are no requirements, an empty list should be |
| 114 | +provided (`enables = []`). This content is already in the index. |
| 115 | + |
| 116 | +The availability of this new syntax should not require an MSRV bump. |
| 117 | +This means we need to make sure that if you use `feature_name = []` in your `Cargo.toml`, |
| 118 | +then the published `Cargo.toml` should as well. |
| 119 | +However, we leave it as an implementation detail whether using `feature_name = { enables =[] }` |
| 120 | +requires an MSRV bump for users of your published package as we have not been |
| 121 | +actively streamlining the workflow for maintaining separate development and |
| 122 | +published MSRVs. |
| 123 | + |
| 124 | +# Drawbacks |
| 125 | + |
| 126 | +[drawbacks]: #drawbacks |
| 127 | + |
| 128 | +- Added complexity to Cargo. Parsing is trivial, but exact implementation |
| 129 | + details do add test surface area |
| 130 | +- Extending the `Cargo.toml` schema, particularly having a field support |
| 131 | + additional types, is disruptive to third-party parsers |
| 132 | + |
| 133 | +# Rationale and alternatives |
| 134 | + |
| 135 | +[rationale-and-alternatives]: #rationale-and-alternatives |
| 136 | + |
| 137 | +This RFC has no impact on the Index Summaries. |
| 138 | +Future RFCs will need to work with that. |
| 139 | + |
| 140 | +## Naming |
| 141 | + |
| 142 | +- `enables` reads better on the line than `enable` |
| 143 | +- `enables` is likely an easier word for non-native speakers than `activates` |
| 144 | +- `required` is used elsewhere to say "this should automatically be available if requirements are met" |
| 145 | + |
| 146 | +## Schema |
| 147 | + |
| 148 | +We could split the special feature syntax (`dep:`, etc) as distinct fields |
| 149 | +but we'd prefer trivial conversion from the "simple" schema to the "detailed" schema, |
| 150 | +like `dependencies`. |
| 151 | +However, we likely would want to prefer using new fields over adding more syntax, |
| 152 | +like with [disabling default features](https://github.com/rust-lang/cargo/issues/3126). |
| 153 | + |
| 154 | +# Prior art |
| 155 | + |
| 156 | +[prior-art]: #prior-art |
| 157 | + |
| 158 | +# Unresolved questions |
| 159 | + |
| 160 | +[unresolved-questions]: #unresolved-questions |
| 161 | + |
| 162 | +# Future possibilities |
| 163 | + |
| 164 | +[future-possibilities]: #future-possibilities |
| 165 | + |
| 166 | +- [Cargo feature descriptions](https://github.com/rust-lang/rfcs/pull/3485) |
| 167 | +- [Cargo feature deprecation](https://github.com/rust-lang/rfcs/pull/3486) |
| 168 | +- [Cargo feature visibility](https://github.com/rust-lang/rfcs/pull/3487) |
| 169 | +- [Cargo feature stability](https://github.com/rust-lang/cargo/issues/10881) |
| 170 | + |
| 171 | +[cargo #12335]: https://github.com/rust-lang/cargo/issues/12235 |
| 172 | +[cargo #10882]: https://github.com/rust-lang/cargo/issues/10882 |
| 173 | +[`cargo-info`]: https://github.com/rust-lang/cargo/issues/948 |
| 174 | +[`deprecated`]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute |
| 175 | +[`deprecated-suggestions`]: https://github.com/rust-lang/rust/issues/94785 |
| 176 | +[discussion on since]: https://github.com/rust-lang/rfcs/pull/3416#discussion_r1172895497 |
| 177 | +[`public_private_dependencies`]: https://rust-lang.github.io/rfcs/1977-public-private-dependencies.html |
| 178 | +[`rustdoc-cargo-configuration`]: https://github.com/rust-lang/rfcs/pull/3421 |
| 179 | +[`tokio`]: https://docs.rs/crate/tokio/latest/features |
| 180 | +[visibility attribute]: https://ant.apache.org/ivy/history/latest-milestone/ivyfile/conf.html |
0 commit comments