Skip to content

Commit 8dd6bff

Browse files
committed
feat: Initial draft
1 parent f46f10b commit 8dd6bff

File tree

1 file changed

+85
-58
lines changed

1 file changed

+85
-58
lines changed

text/0000-remove-implicit-features.md

Lines changed: 85 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,124 @@
1-
- Feature Name: (fill me in with a unique ident, `my_awesome_feature`)
2-
- Start Date: (fill me in with today's date, YYYY-MM-DD)
1+
- Feature Name: `remove-implicit-feature`
2+
- Start Date: 2023-09-18
33
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
44
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
55

66
# Summary
77
[summary]: #summary
88

9-
One paragraph explanation of the feature.
9+
By default, cargo will treat any optional dependency as a feature.
10+
As of cargo 1.60, these can be disabled by declaring a feature that activates
11+
the optional dependency as `dep:<name>`
12+
(see [RFC #3143](https://rust-lang.github.io/rfcs/3143-cargo-weak-namespaced-features.html)).
13+
14+
On the next edition, cargo will stop exposing optional dependencies as features
15+
implicitly, requiring users to add `foo = ["dep:foo"]` if they still want it exposed.
1016

1117
# Motivation
1218
[motivation]: #motivation
1319

14-
Why are we doing this? What use cases does it support? What is the expected outcome?
20+
While implicit features offer a low overhead way of defining features,
21+
- It is easy to overlook using `dep:` when the optional dependency is not intended to be exposed
22+
- Making it easy for crate authors to use the wrong syntax and be met with errors ([rust-lang/cargo#10125](https://github.com/rust-lang/cargo/issues/10125))
23+
- Potentially breaking people if they are later removed ([rust-lang/cargo#12687)](https://github.com/rust-lang/cargo/pull/12687))
24+
- Leading to confusing choices when `cargo add` lists features that look the same (e.g. `cargo add serde` showing `derive` and `serde_derive`)
25+
- Leading to confusing errors for callers when they reference the dependency, instead of the feature, and things don't work right
26+
- Tying feature names to dependency names is a code smell because it ties the API to the implementation
27+
- It requires people and tools to deal with this special case ([rust-lang/cargo#10543](https://github.com/rust-lang/cargo/issues/10543))
28+
- Granted, anything having to deal with old editions will still have to deal with this
1529

1630
# Guide-level explanation
1731
[guide-level-explanation]: #guide-level-explanation
1832

19-
Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means:
2033

21-
- Introducing new named concepts.
22-
- Explaining the feature largely in terms of examples.
23-
- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible.
24-
- If applicable, provide sample error messages, deprecation warnings, or migration guidance.
25-
- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers.
26-
- Discuss how this impacts the ability to read, understand, and maintain Rust code. Code is read and modified far more often than written; will the proposed feature make code easier to maintain?
2734

28-
For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms.
35+
Updated documentation:
36+
37+
## Optional Dependencies
38+
*(Replaces the [same section in the book](https://doc.rust-lang.org/cargo/reference/features.html#optional-dependencies))*
39+
40+
Dependencies can be marked "optional", which means they will not be compiled
41+
by default.
42+
43+
For example, let's say that our 2D image processing library uses
44+
an external package to handle GIF images. This can be expressed like this:
45+
46+
```toml
47+
[features]
48+
gif = ["dep:giffy"]
49+
50+
[dependencies]
51+
giffy = { version = "0.11.1", optional = true }
52+
```
53+
54+
This means that this dependency will only be included if the `gif`
55+
feature is enabled.
56+
In addition to `cfg(feature = "gif")` syntax, you can reference this as
57+
`cfg(feature = "giffy")` in the code though users may get confused at error
58+
messages when used on a public API.
59+
60+
> **Note**: Prior to the 202X edition, features were implicitly created for
61+
> optional dependencies not referenced via `dep:`.
62+
63+
> **Note**: Another way to optionally include a dependency is to use
64+
> [platform-specific dependencies]. Instead of using features, these are
65+
> conditional based on the target platform.
2966
3067
# Reference-level explanation
3168
[reference-level-explanation]: #reference-level-explanation
3269

33-
This is the technical portion of the RFC. Explain the design in sufficient detail that:
70+
## Existing editions
71+
72+
For existing editions, `cargo` will warn when parsing a workspace member's
73+
package when an optional dependency is not referenced via `dep:` in the
74+
features ([rust-lang/cargo#9088](https://github.com/rust-lang/cargo/issues/9088)) using the
75+
planned warning control system ([rust-lang/cargo#12235](https://github.com/rust-lang/cargo/issues/12235)).
76+
The warning will be named something like `cargo::implicit_feature` and be part
77+
of the `cargo::rust-202X-compatibility` group.
78+
79+
Suggested text:
80+
```
81+
implicit features for optional dependencies is deprecated and will be unavailable in the 202X edition.
82+
```
83+
This would be machine applicable with a suggestion to add `foo = ["dep:foo"]`. `cargo fix` would then insert this feature.
84+
85+
## Next edition
3486

35-
- Its interaction with other features is clear.
36-
- It is reasonably clear how the feature would be implemented.
37-
- Corner cases are dissected by example.
87+
On the next edition, this warning will be a hard error.
3888

39-
The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work.
89+
Suggested text:
90+
```
91+
unused optional dependency `foo`. To use it, a feature must activate it with `dep:foo` syntax
92+
```
93+
This could be machine applicable with a suggestion to add `foo = ["dep:foo"]`.
94+
95+
## Other
96+
97+
To help users through this, `cargo add` will be updated so that `cargo add foo
98+
--optional` will create a `foo = ["dep:foo"]` if its not already referenced by
99+
another features
100+
([rust-lang/cargo#11010](https://github.com/rust-lang/cargo/issues/11010)).
40101

41102
# Drawbacks
42103
[drawbacks]: #drawbacks
43104

44-
Why should we *not* do this?
105+
- Some boilerplate is needed for all features, rather than just a subset
106+
- Extra ecosystem churn on the next edition update
45107

46108
# Rationale and alternatives
47109
[rationale-and-alternatives]: #rationale-and-alternatives
48110

49-
- Why is this design the best in the space of possible designs?
50-
- What other designs have been considered and what is the rationale for not choosing them?
51-
- What is the impact of not doing this?
52-
- If this is a language proposal, could this be done in a library or macro instead? Does the proposed change make Rust code easier or harder to read, understand, and maintain?
111+
Instead of an error, optional dependencies could be
112+
- Make optional dependencies private features ([RFC #3487](https://github.com/rust-lang/rfcs/pull/3487))
113+
- Seems like the need for this would be relatively low and be less obvious
114+
- We could still transition to this in the future
115+
- Allow access to the feature via `#[cfg(accessible)]` ([RFC #2523](https://rust-lang.github.io/rfcs/2523-cfg-path-version.html))
53116

54117
# Prior art
55118
[prior-art]: #prior-art
56119

57-
Discuss prior art, both the good and the bad, in relation to this proposal.
58-
A few examples of what this can include are:
59-
60-
- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had?
61-
- For community proposals: Is this done by some other community and what were their experiences with it?
62-
- For other teams: What lessons can we learn from what other communities have done here?
63-
- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background.
64-
65-
This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture.
66-
If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages.
67-
68-
Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC.
69-
Please also take into consideration that rust sometimes intentionally diverges from common language features.
70-
71120
# Unresolved questions
72121
[unresolved-questions]: #unresolved-questions
73122

74-
- What parts of the design do you expect to resolve through the RFC process before this gets merged?
75-
- What parts of the design do you expect to resolve through the implementation of this feature before stabilization?
76-
- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC?
77-
78123
# Future possibilities
79124
[future-possibilities]: #future-possibilities
80-
81-
Think about what the natural extension and evolution of your proposal would
82-
be and how it would affect the language and project as a whole in a holistic
83-
way. Try to use this section as a tool to more fully consider all possible
84-
interactions with the project and language in your proposal.
85-
Also consider how this all fits into the roadmap for the project
86-
and of the relevant sub-team.
87-
88-
This is also a good place to "dump ideas", if they are out of scope for the
89-
RFC you are writing but otherwise related.
90-
91-
If you have tried and cannot think of any future possibilities,
92-
you may simply state that you cannot think of anything.
93-
94-
Note that having something written down in the future-possibilities section
95-
is not a reason to accept the current or a future RFC; such notes should be
96-
in the section on motivation or rationale in this or subsequent RFCs.
97-
The section merely provides additional information.

0 commit comments

Comments
 (0)