Skip to content

Commit f3b862b

Browse files
committed
Update documentation about private feature usage
1 parent 397d47e commit f3b862b

File tree

1 file changed

+42
-33
lines changed

1 file changed

+42
-33
lines changed

text/0000-feature-metadata.md

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,10 @@ The following keys would be allowed in a feature table:
7575
- `public`: A boolean flag defaulting to `true` that indicates whether or not
7676
downstream crates should be allowed to use this feature.
7777

78-
If a downstream crate attempts to use the features `baz` and `qux`, they will
79-
see messages like the following:
78+
Attempting to use a private feature on a downstream crate will result in
79+
messages like the following:
8080

8181
```
82-
warning: feature `quux` on crate `mycrate` is deprecated since version
83-
1.2.3: "don't use this!"
84-
8582
error: feature `baz` on crate `mycrate` is private and cannot be used by
8683
downstream crates
8784
```
@@ -136,15 +133,12 @@ attribute in Rust source. The value can be a boolean, string, or an object with
136133
- If not specified, the default is `false`
137134

138135
If a downstream crate attempts to use a feature marked `deprecated`, Cargo
139-
should produce a warning. There are two exceptions to this:
140-
141-
- If a `since` is specified that is later than the crate's current version,
142-
this warning should not be emitted.
143-
- This warning should not be emitted for crates that reexport the feature
144-
under a feature also marked deprecated. For example: crate `foo` exports
145-
feature `phooey`, and crate `bar` exports feature `barred = ["foo/phooey"]`.
146-
If `foo` markes `bar` as deprecated, checking `bar` will emit a warning
147-
unless `barred` is also marked `deprecated.
136+
should produce a warning. This warning should not be emitted for crates that
137+
reexport the feature under a feature also marked deprecated. For example: crate
138+
`foo` exports feature `phooey`, and crate `bar` exports feature
139+
`barred = ["foo/phooey"]`. If `foo` markes `bar` as deprecated, running any
140+
cargo action on `bar` will emit a warning unless `barred` is also marked
141+
`deprecated.
148142

149143
Accessing this information will require access to the manifest.
150144

@@ -158,26 +152,41 @@ crates.
158152
The default `true` is not consistent with [`public_private_dependencies`] or
159153
Rust's `pub`, but is a reasonable default to be consistent with the current
160154
behavior so that either `feature = []` or `feature = { "enables" = [] }` will
161-
return the same result.
155+
result in the same configuration.
162156

163157
The name `public` was chosen in favor of `pub` to be consistent with the
164158
[`public_private_dependencies`] RFC, and to match the existing style of using
165159
non-truncated words as keys.
166160

167161
In general, marking a feature `public = false` should make tooling treat the
168-
feature as non-public API. That includes:
162+
feature as non-public API. This is described as the following:
169163

164+
- The feature is always usable within the same crate:
165+
- Enablement by other features, e.g. `foo = { enables =
166+
[some-private-feature] }`, is allowed
167+
- Using the feature in integration tests is allowed
168+
- Using the feature in benchmarks is allowed
170169
- The feature should not be accepted by `cargo add --features`
171170
- The feature should not be reported from `cargo add`'s feature output report
172171
- Once `rustdoc` is able to consume feature metadata, `rustdoc` should not
173172
document these features unless `--document-private-items` is specified
174173
- A future tool like `cargo info` shouldn't display information about these
175174
features
175+
- Explicitly specifying the feature via `--features somecrate/private-feature`
176+
will allow enabling a private feature that would otherwise be forbidden
177+
178+
Attempting to use a private feature in any of the forbidden cases should result
179+
in an error. Exact details of how features work will likely be refined during
180+
implementation and experimentation.
181+
182+
Two sample use cases for `public = false` include:
183+
184+
- `docs.rs` having a way to know which features should be hidden
185+
- Features that are included in feature chains (feature `a` enables feature
186+
`b`) but not meant for public consumption could be marked not public
176187

177-
There likely needs to be an escape hatch for this for things like benchmarks -
178-
RFC TBD on how this works.
179188

180-
This feature would require adjustments to the index for full support. This RFC
189+
This feature requires adjustments to the index for full support. This RFC
181190
proposes that it would be acceptable for the first implementation to simply
182191
strip private features from the manifest; this meanss that there will be no way
183192
to `cfg` based on these features.
@@ -186,12 +195,6 @@ Full support does not need to happen immediately, since it will require this
186195
information be present in the index. [Index changes] describes how this can take
187196
place.
188197

189-
Two sample use cases for `public = false` include:
190-
191-
- `docs.rs` having a way to know which features should be hidden
192-
- Features that are included in feature chains (feature `a` enables feature
193-
`b`) but not meant for public consumption could be marked not public
194-
195198
# General Implementation & Usage
196199

197200
Use cases for this information will likely develop with time, but one of the
@@ -300,16 +303,22 @@ ignore this key, newer Cargo would be able to merge `features`, `features2`, and
300303

301304
[unresolved-questions]: #unresolved-questions
302305

303-
- If we use the semantics as-written, should there be a
304-
`--allow-private-features` flag? Or how should a user opt in?
305306
- Rather than being consistent with `rustdoc` and accepting markdown, should
306307
the `doc` key be consistent with `package.description` and only support
307308
plain text? This RFC proposes making this decision at time of
308309
implementation, the challenges of supporting markdown are better understood.
309-
310-
It is worth noting that not all of these feature flags need to be made available
311-
at once. `enables` needs to be implemented first, but support for all others
312-
could be added over time.
310+
- Are the semantics of `public` proposed in this RFC suitable? Should private
311+
features be usable in examples or integration tests without a `--features`
312+
argument?
313+
- Should there be a simple `--allow-private-features` flag that allows using
314+
all features, such as for crater runs? This can be decided during
315+
implementation.
316+
- How should `since` work with the `deprecated` key? This can be decided
317+
during implementation or droped entirely.
318+
319+
It is worth noting that not all of these new keys need to be made available at
320+
once. `enables` needs to be implemented first, but support for all others could
321+
be added over time.
313322

314323
# Future possibilities
315324

@@ -331,8 +340,8 @@ could be added over time.
331340
- At some point, the decision to not include `doc` in the index could be
332341
reevaluated. Including only the first (summary) line of `doc` could be a
333342
possibility.
334-
- The `public` feature flags could be used to allow optional dev dependencies.
335-
See: <https://github.com/rust-lang/cargo/issues/1596>
343+
- The `public` option could be used to allow optional dev dependencies. See:
344+
<https://github.com/rust-lang/cargo/issues/1596>
336345
- `cargo add` can show the `doc` and `deprecated` summary with the listed
337346
features.
338347
- [`cargo-info`] can use this information to provide feature descriptions.

0 commit comments

Comments
 (0)