Skip to content

Commit 9fe5140

Browse files
authored
Merge pull request #3416 from tgross35/feature-descriptions-doc-cfg
RFC: Unblock Cargo feature metadata
2 parents e70fa73 + a8c6163 commit 9fe5140

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

text/3416-feature-metadata.md

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
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

Comments
 (0)