From 5f064babaeb10f19aaba52312928b91266014740 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 11 Nov 2022 15:50:37 -0500 Subject: [PATCH 1/9] at-least-one-feature: Copy template --- text/0000-at-least-one-feature.md | 97 +++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 text/0000-at-least-one-feature.md diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md new file mode 100644 index 00000000000..a2ab4c4c8a6 --- /dev/null +++ b/text/0000-at-least-one-feature.md @@ -0,0 +1,97 @@ +- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) +- Start Date: (fill me in with today's date, YYYY-MM-DD) +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +# Summary +[summary]: #summary + +One paragraph explanation of the feature. + +# Motivation +[motivation]: #motivation + +Why are we doing this? What use cases does it support? What is the expected outcome? + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: + +- Introducing new named concepts. +- Explaining the feature largely in terms of examples. +- 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. +- If applicable, provide sample error messages, deprecation warnings, or migration guidance. +- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. +- 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? + +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. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +This is the technical portion of the RFC. Explain the design in sufficient detail that: + +- Its interaction with other features is clear. +- It is reasonably clear how the feature would be implemented. +- Corner cases are dissected by example. + +The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. + +# Drawbacks +[drawbacks]: #drawbacks + +Why should we *not* do this? + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +- Why is this design the best in the space of possible designs? +- What other designs have been considered and what is the rationale for not choosing them? +- What is the impact of not doing this? +- 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? + +# Prior art +[prior-art]: #prior-art + +Discuss prior art, both the good and the bad, in relation to this proposal. +A few examples of what this can include are: + +- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? +- For community proposals: Is this done by some other community and what were their experiences with it? +- For other teams: What lessons can we learn from what other communities have done here? +- 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. + +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. +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. + +Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. +Please also take into consideration that rust sometimes intentionally diverges from common language features. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +- What parts of the design do you expect to resolve through the RFC process before this gets merged? +- What parts of the design do you expect to resolve through the implementation of this feature before stabilization? +- 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? + +# Future possibilities +[future-possibilities]: #future-possibilities + +Think about what the natural extension and evolution of your proposal would +be and how it would affect the language and project as a whole in a holistic +way. Try to use this section as a tool to more fully consider all possible +interactions with the project and language in your proposal. +Also consider how this all fits into the roadmap for the project +and of the relevant sub-team. + +This is also a good place to "dump ideas", if they are out of scope for the +RFC you are writing but otherwise related. + +If you have tried and cannot think of any future possibilities, +you may simply state that you cannot think of anything. + +Note that having something written down in the future-possibilities section +is not a reason to accept the current or a future RFC; such notes should be +in the section on motivation or rationale in this or subsequent RFCs. +The section merely provides additional information. From 7b90ea37337680f5bf0198c0f07cc419dad6e9bf Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 11 Nov 2022 17:39:06 -0500 Subject: [PATCH 2/9] at-least-one-feature: Initial draft --- text/0000-at-least-one-feature.md | 195 +++++++++++++++++++++--------- 1 file changed, 140 insertions(+), 55 deletions(-) diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index a2ab4c4c8a6..295c2fed918 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -1,97 +1,182 @@ -- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) -- Start Date: (fill me in with today's date, YYYY-MM-DD) +- Feature Name: `at-least-one-feature` +- Start Date: 2022-11-11 - RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) # Summary [summary]: #summary -One paragraph explanation of the feature. +Allow packages to require that dependencies on them must specify at least one feature (the `default` feature counts). +This avoids backwards compatibility problems with `default-features = false`. # Motivation [motivation]: #motivation -Why are we doing this? What use cases does it support? What is the expected outcome? +A major use-case of Cargo features to take previously mandatory functionality and make it optional. +This is usual done in order to make the code more portable than it was previously, while not breaking existing consumers of the library. +Consider this example which shoes both work works and what doesn't: -# Guide-level explanation -[guide-level-explanation]: #guide-level-explanation +1. Library has no features. + +2. A `foo` feature is added, gating functionality that already existed. + It is on by default. + `no-default-features = true` can be used in which some dependencies only needed for `foo` can be avoided. + Yay! + +3. A `bar` feature is added, gating functionality that already existed. + + - Suppose it is off by default. + Oh no! + All Existing use-cases break because the functionality that depends on `bar` goes away. + + - Suppose it is on by default, or depended-upon by `bar`. + Oh no! + Existing `no-default-features = true` are now broken! + They want a feature set of `{bar}` which would correspond to the old `{}`, but there is no way to arrange it. + +In step two, we could "ret-con" the empty feature set with the `default` feature. +But this is a trick that can only be pulled once. +The second time around, we already have a default feature; we are out of luck. -Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: +The previous attempts attempted to make new default features, or migrate the requested feature sets. +But that is complex. +There is exactly a simpler solution: simply require that *some* feature always be depended-upon. -- Introducing new named concepts. -- Explaining the feature largely in terms of examples. -- 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. -- If applicable, provide sample error messages, deprecation warnings, or migration guidance. -- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. -- 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? +To see why this works, it helps to first see that step 2 was *already* broken. +Here's the thing, even though there previously were not any features, that *doesn't* mean there were not any `no-default-features = true` users! +Sure, it wouldn't do anything for crate with new features, but one can still use it. +Then when just `bar` is added, we already have a problem, because the `default` feature will no "catch" all the existing users --- +the mischievous users that were already using `no-default-features = true` will have their code broken! -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. +This brings us to the heart of the problem. +So long as users are depending on "something", we can be careful to make sure those features keep their meaning. +But when users are depending on nothing at all with `no-default-features = true` and an empty feature set, we have nothing to "hook into". +The simple solution is just to rule out that problem entirely! + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +Packages with +```toml +[package] +at-least-one-feature = true +``` +are easier to maintain! +You don't need to worry about the `no-default-features = true, features = []` case anymore. +You can be sure that all consumers must dependent on either `default` or a regular named feature. + +Whenever you want to make existing functionality more conditional, simply extend the set of features the code relies on with a new feature, and ensure existing features depend on that feature. + +For example: +```rust +fn my_fun_that_allocates() { .. } + +#[cfg(all(feature = "foo", feature = "bar"))] +fn my_weird_fun_that_allocates() { .. } +``` +becomes: +```rust +#[cfg(feature = "baz")] +fn my_fun_that_allocates() { .. } + +#[cfg(all(feature = "foo", feature = "bar", feature = "baz"))] +fn my_weird_fun_that_allocates() { .. } +``` + +And the corresponding `Cargo.toml`: +```toml +[features] +default = ["foo"] +bar = ["foo"] +``` +becomes: +```toml +[features] +default = ["foo", "baz"] +foo = ["baz"] +bar = ["foo"] # no need to add "baz" because "bar" picks it up +``` # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -This is the technical portion of the RFC. Explain the design in sufficient detail that: +Depending on a +```toml +[package] +at-least-one-feature = true +``` +crate with an empty feature set is disallowed and invalidates the solution. +The `default` feature counts as a member of that set when `default-features = true`. + +The solver shall avoid such solutions (so as not break old versions of libraries without `at-least-one-feature` being "discoverable"). + +## Provisional Theory + +We can begin to formalize library compatibility with something like +[this](https://q.uiver.app/?q=WzAsNCxbMCwwLCJcXG1hdGhjYWx7UF/PiX0oXFxtYXRocm17RmVhdHVyZXN9X3tcXG1hdGhybXtPbGR9fSkiXSxbMSwwLCJcXG1hdGhjYWx7UF/PiX0oXFxtYXRocm17RmVhdHVyZXN9X3tcXG1hdGhybXtOZXd9fSkiXSxbMCwxLCJcXG1hdGhybXtSdXN0fSJdLFsxLDEsIlxcbWF0aHJte1J1c3R9Il0sWzAsMSwiXFxtYXRocm17c2FtZVxcIG5hbWVzfSIsMCx7InN0eWxlIjp7InRhaWwiOnsibmFtZSI6Imhvb2siLCJzaWRlIjoiYm90dG9tIn19fV0sWzAsMiwiXFwjW1xcbWF0aHR0e2NmZ30oLi4uKV1fXFxtYXRocm17T2xkfSIsMl0sWzEsMywiXFwjW1xcbWF0aHR0e2NmZ30oLi4uKV1fXFxtYXRocm17TmV3fSJdLFszLDIsIlxcbWF0aHJte2BgdXBjYXN0XCJcXCBsaWJyYXJ5XFwgaW50ZXJmYWNlc30iXV0=) +[commutative diagram](https://en.wikipedia.org/wiki/Commutative_diagram). -- Its interaction with other features is clear. -- It is reasonably clear how the feature would be implemented. -- Corner cases are dissected by example. +- The old and new features form a partial order -The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. +- P_ω takes those partial orders to the partial order of their downsets. + (That is, sets of features with the implied features from feature dependencies "filled in", ordered by inclusion.) + +- "same names" maps the old downsets to the new downsets, filling in any newly implied features as needed. + +- `#[cfg(...)]` is the mapping of feature sets to exposed library interfaces + +- "'upcast' library interfaces" forgets whatever unrelated new stuff was added in the new library version + +The idea is that going from the old features directly to the old interfaces, or going the "long way" from old features to new features to new interfaces to old interfaces should yield the same result. + +For the more part, features can be "interspersed" anywhere the old feature partial order to make the new feature partial order. +However, this is an exception! +The old empty downset becomes the new empty downset, which means nothing can be added below it. +This is the `default-features = false` gotcha! + +When we disallow the empty feature set, we are replacing P_ω with the "free join-semilattice" construction. +We are enriching features with the ∨ binary operator but no ⊥ identity element. +There is no empty downset becomes empty downset constraint, and thus we are free to add new features below all the others all we want. # Drawbacks [drawbacks]: #drawbacks -Why should we *not* do this? +I can't really think of a reason, it's much simpler than the prior attempts! # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives -- Why is this design the best in the space of possible designs? -- What other designs have been considered and what is the rationale for not choosing them? -- What is the impact of not doing this? -- 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? +An alternative is not to ban the empty feature set, but ensure it always translates to the empty library. +I.e. to require that *all* items must be dependent upon *some* feature; everything needs a `cfg`. -# Prior art -[prior-art]: #prior-art +Returning to our half-worked-out theory, instead of banning a notion of a ⊥ empty feature set that must be preserved from the old library to the new (removing a requirement), we are adding a *new* requirement that the ⊥ feature set must map to the ⊥ Rust interface. +We still have the restriction that new features can be added below, but this restriction is no longer a problem: +there is no point of adding such a new minimal feature because there is nothing left to `cfg`-out! -Discuss prior art, both the good and the bad, in relation to this proposal. -A few examples of what this can include are: +This solution is more mathematically elegant, but it seems harder to implement. +It is unclear how Cargo could require the Rust code to obey this property without new infra like the portability lint. -- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? -- For community proposals: Is this done by some other community and what were their experiences with it? -- For other teams: What lessons can we learn from what other communities have done here? -- 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. +# Prior art +[prior-art]: #prior-art -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. -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. +This is a well-known problem. +See just-rejected [#3283](https://github.com/rust-lang/rfcs/pull/3283), +and my previous retracted [#3146](https://github.com/rust-lang/rfcs/pull/3146). -Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. -Please also take into consideration that rust sometimes intentionally diverges from common language features. +I think this is much simpler than the other two. # Unresolved questions [unresolved-questions]: #unresolved-questions -- What parts of the design do you expect to resolve through the RFC process before this gets merged? -- What parts of the design do you expect to resolve through the implementation of this feature before stabilization? -- 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? +It would be nice to completely work out the theory. # Future possibilities [future-possibilities]: #future-possibilities -Think about what the natural extension and evolution of your proposal would -be and how it would affect the language and project as a whole in a holistic -way. Try to use this section as a tool to more fully consider all possible -interactions with the project and language in your proposal. -Also consider how this all fits into the roadmap for the project -and of the relevant sub-team. - -This is also a good place to "dump ideas", if they are out of scope for the -RFC you are writing but otherwise related. - -If you have tried and cannot think of any future possibilities, -you may simply state that you cannot think of anything. +The `default-features = false` syntax is clunky. +A new edition could say that an explicit feature list always means `default-features = []`, but that `default` can be used in feature lists. +With this change, "must depend on one feature, including possibly the default feature" becomes easier to explain: -Note that having something written down in the future-possibilities section -is not a reason to accept the current or a future RFC; such notes should be -in the section on motivation or rationale in this or subsequent RFCs. -The section merely provides additional information. +- `[]` disallowed +- `["default"]` allowed +- `["foo"]` allowed From 4c452e1d3f5329a0b320a7350b33a4ed09d04e7d Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 11 Nov 2022 17:46:49 -0500 Subject: [PATCH 3/9] at-least-one-feature: Screen shot diagram Unfortunately can't get SVG https://github.com/varkor/quiver/issues/8 --- resources/0000-at-least-one-feature.png | Bin 0 -> 72682 bytes text/0000-at-least-one-feature.md | 7 ++++--- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 100644 resources/0000-at-least-one-feature.png diff --git a/resources/0000-at-least-one-feature.png b/resources/0000-at-least-one-feature.png new file mode 100644 index 0000000000000000000000000000000000000000..e08ca13d402dfabff9c8b989ec1e7f69a7944e92 GIT binary patch literal 72682 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 Lb-7Gg6QBPDTR?Q{ literal 0 HcmV?d00001 diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index 295c2fed918..606a8b07b58 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -112,9 +112,10 @@ The solver shall avoid such solutions (so as not break old versions of libraries ## Provisional Theory -We can begin to formalize library compatibility with something like -[this](https://q.uiver.app/?q=WzAsNCxbMCwwLCJcXG1hdGhjYWx7UF/PiX0oXFxtYXRocm17RmVhdHVyZXN9X3tcXG1hdGhybXtPbGR9fSkiXSxbMSwwLCJcXG1hdGhjYWx7UF/PiX0oXFxtYXRocm17RmVhdHVyZXN9X3tcXG1hdGhybXtOZXd9fSkiXSxbMCwxLCJcXG1hdGhybXtSdXN0fSJdLFsxLDEsIlxcbWF0aHJte1J1c3R9Il0sWzAsMSwiXFxtYXRocm17c2FtZVxcIG5hbWVzfSIsMCx7InN0eWxlIjp7InRhaWwiOnsibmFtZSI6Imhvb2siLCJzaWRlIjoiYm90dG9tIn19fV0sWzAsMiwiXFwjW1xcbWF0aHR0e2NmZ30oLi4uKV1fXFxtYXRocm17T2xkfSIsMl0sWzEsMywiXFwjW1xcbWF0aHR0e2NmZ30oLi4uKV1fXFxtYXRocm17TmV3fSJdLFszLDIsIlxcbWF0aHJte2BgdXBjYXN0XCJcXCBsaWJyYXJ5XFwgaW50ZXJmYWNlc30iXV0=) -[commutative diagram](https://en.wikipedia.org/wiki/Commutative_diagram). +We can begin to formalize library compatibility with something like this +[commutative diagram](https://en.wikipedia.org/wiki/Commutative_diagram): +![commutative diagram](../resources/0000-at-least-one-feature.png) +[(generated from here)](https://q.uiver.app/?q=WzAsNCxbMCwwLCJcXG1hdGhjYWx7UF/PiX0oXFxtYXRocm17RmVhdHVyZXN9X3tcXG1hdGhybXtPbGR9fSkiXSxbMSwwLCJcXG1hdGhjYWx7UF/PiX0oXFxtYXRocm17RmVhdHVyZXN9X3tcXG1hdGhybXtOZXd9fSkiXSxbMCwxLCJcXG1hdGhybXtSdXN0fSJdLFsxLDEsIlxcbWF0aHJte1J1c3R9Il0sWzAsMSwiXFxtYXRocm17c2FtZVxcIG5hbWVzfSIsMCx7InN0eWxlIjp7InRhaWwiOnsibmFtZSI6Imhvb2siLCJzaWRlIjoiYm90dG9tIn19fV0sWzAsMiwiXFwjW1xcbWF0aHR0e2NmZ30oLi4uKV1fXFxtYXRocm17T2xkfSIsMl0sWzEsMywiXFwjW1xcbWF0aHR0e2NmZ30oLi4uKV1fXFxtYXRocm17TmV3fSJdLFszLDIsIlxcbWF0aHJte2BgdXBjYXN0XCJcXCBsaWJyYXJ5XFwgaW50ZXJmYWNlc30iXV0=) - The old and new features form a partial order From c37e11bdbe2dd6fd7bb55c987dc42b8582f19158 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 12 Nov 2022 08:58:58 -0500 Subject: [PATCH 4/9] at-least-one-feature: Mention bad names downside --- text/0000-at-least-one-feature.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index 606a8b07b58..e6e5ca0d825 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -142,7 +142,21 @@ There is no empty downset becomes empty downset constraint, and thus we are free # Drawbacks [drawbacks]: #drawbacks -I can't really think of a reason, it's much simpler than the prior attempts! +## Bad names over time + +A downside of this proposal is that one has to resort to increasingly bad names. +Take [seanmonstar/warp#968](https://github.com/seanmonstar/warp/issues/968) as an example. +Warp currently ships HTTP2 support by default. This means that in order to be able to ship a version without http2, _all current features must depend on HTTP2_. +This means creating new `websocket-without-http2`, `tls-without-http2`, `compression-without-http2`, `compression-brotli-without-http2`, `compression-gzip-without-http2` features in order for other crates to depend on them without pulling in http2 support. + +My sense that while that is a downside, it is better to first walk that run. +Do this and the problem is solved. +And if new opt-out features are only occasionally added, it might be fine. +But, liberated from back-compat issues, new opt-features may become more popular, and then people will want sort of "feature migrations" so they can "reuse the good names" and avoid this `...-without-...` bussiness. + +But just cause we predict that doesn't mean we can avoid this first step! +The "walking vs running" idea that feature migrations take significantly more work, +and if we never first "unlock" increased demand for opt-out features via something cheap like this, we'll never be able to justify those costs. # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives From 6168951a91590625bb942b0f159ce6b43a19523d Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 12 Nov 2022 09:16:48 -0500 Subject: [PATCH 5/9] at-least-one-feature: Compatibility of `at-least-one-feature = true` itself --- text/0000-at-least-one-feature.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index e6e5ca0d825..1a79338d8f5 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -139,6 +139,26 @@ When we disallow the empty feature set, we are replacing P_ω with the "free joi We are enriching features with the ∨ binary operator but no ⊥ identity element. There is no empty downset becomes empty downset constraint, and thus we are free to add new features below all the others all we want. +# Compatibility of `at-least-one-feature = true` itself + +At first, it seems like adding `at-least-one-feature = true` to a new version of a crate is a breaking change. +But, I don't think it is. +We have to step back a bit: a breaking change is one that if it *didn't* come with an increasing major version, would result in valid Cargo plans that do not build. +Yes, adding `at-least-one-feature = true` to a newer version of a crate will result in depending (not dependent) crate that do not specify a feature for that dependency being unable to upgrade. +But that's it! +Those crates will *not* have their dependencies upgraded incorrectly, resulting in a build failure, and thus there is no problem. + +(This is very much analogous to the situation with minimum Rust versions. +Updating the minimum Rust version in a new version of a crate is not a breaking change. +Some users with old versions will be unable to use the new version, but no one will be falsely upgraded resulting in a build failure. + +Indeed, that point of being able to express the minimum Rust version is precisely to *avoid* bumping the minimum supported version being a breaking change. +Before, Cargo was unaware of this dependency on the compiler, and so raising the implicit lower bound had to be a breaking change. +Now, Cargo is aware of the dependency and it is no longer a breaking change. + +Putting it altogether, in general we can say that bumping major versions is a tool of last result to account for issues Cargo can't directly know about. +If Cargo can be directly made aware of the issue, then there is no "residual breakage" requiring a major version bump.) + # Drawbacks [drawbacks]: #drawbacks From 1c25cd971787b76ff3b132840e18366875c9f6ea Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 12 Nov 2022 10:00:54 -0500 Subject: [PATCH 6/9] at-least-one-feature: Greatly expand "alternatives" section Prior RFCs are moved to there. --- text/0000-at-least-one-feature.md | 100 ++++++++++++++++++++++++++---- 1 file changed, 88 insertions(+), 12 deletions(-) diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index 1a79338d8f5..8a98275ae2e 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -107,7 +107,7 @@ at-least-one-feature = true ``` crate with an empty feature set is disallowed and invalidates the solution. The `default` feature counts as a member of that set when `default-features = true`. - + The solver shall avoid such solutions (so as not break old versions of libraries without `at-least-one-feature` being "discoverable"). ## Provisional Theory @@ -169,18 +169,19 @@ Take [seanmonstar/warp#968](https://github.com/seanmonstar/warp/issues/968) as a Warp currently ships HTTP2 support by default. This means that in order to be able to ship a version without http2, _all current features must depend on HTTP2_. This means creating new `websocket-without-http2`, `tls-without-http2`, `compression-without-http2`, `compression-brotli-without-http2`, `compression-gzip-without-http2` features in order for other crates to depend on them without pulling in http2 support. +Note that this is only a problem for new features that existing features or orthogonal too. +In many cases, existing features will naturally (not just for back compat) depend on the new features, and then there is no need or possibility to introduce `...-without-...` siblings to those features. + My sense that while that is a downside, it is better to first walk that run. Do this and the problem is solved. -And if new opt-out features are only occasionally added, it might be fine. -But, liberated from back-compat issues, new opt-features may become more popular, and then people will want sort of "feature migrations" so they can "reuse the good names" and avoid this `...-without-...` bussiness. - -But just cause we predict that doesn't mean we can avoid this first step! -The "walking vs running" idea that feature migrations take significantly more work, -and if we never first "unlock" increased demand for opt-out features via something cheap like this, we'll never be able to justify those costs. +We can add feature migrations later once there is more demand. +See the Alternatives section for more details. # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives +## Empty feature set is empty library. + An alternative is not to ban the empty feature set, but ensure it always translates to the empty library. I.e. to require that *all* items must be dependent upon *some* feature; everything needs a `cfg`. @@ -191,14 +192,89 @@ there is no point of adding such a new minimal feature because there is nothing This solution is more mathematically elegant, but it seems harder to implement. It is unclear how Cargo could require the Rust code to obey this property without new infra like the portability lint. +Finally, in a sense these variations are actually isomorphic. +If no one can request the empty feature set, no one can observe what library interface that corresponds to. +There is no reason to conclude that it *isn't* the empty library. + +## RFC [#3146](https://github.com/rust-lang/rfcs/pull/3146) + +This more more expensive solution aimed to solve the "running out of good names" problem this has. + +Returning to our commutative diagram, instead of + +- removing the ⊥ feature downset (this proposal) + +- mandating the ⊥ feature downset correspond to ⊥ the empty library interface (first alternative, extra rules on the vertical mappings in diagrams) + +We can instead + +- allow customizing the mapping from old feature names to new feature names (customizing top horizontal mapping) + +This works and allows giving things the "right" names" every time, but is much work work to implement. + +I think it might make sense to do this someday, but it is better to start with this. +My thinking about this is basically "walk before run". +Today, that would be lots of work for an obscure problem, and a solution that downstream crates need to know about because it affects how dependencies are written. +However if we do this first, "opt-out features" are poised to become much more popular now that they are no longer a compatibility hazard. +We can evaluate both that new popularity, and the incidence of the "bad name" problem in *practice*, and use that to justify a more heavyweight solutions. + +## RFC [#3283](https://github.com/rust-lang/rfcs/pull/3283) + +This proposal adds a new notion of a "feature base", which aims to essential provide more `default-features = false` options rather than just one forever. +`default-features = false` is ret-conned as the first feature base. + +My view is that that RFC is pretty close to being this one in disguise. +A "feature base" is just a feature. +The fact that there is always one "feature base" is just another way of accomplishing the "at least one feature" +restriction. + +The main difference is that `default-features = false` is ret-conned as a feature to allow for existing users. +That can be thought of from the perspective of this RFC as a "one-off" feature migration to get reverse dependencies predating the use of `at-least-one-feature = true` on to a feature so they retroactively abide by the "at least one feature" rule. + +## "Negative features" + +I take a pretty dim view of this. +It is easy to say that one wants negative features; it is harder to actually give a proper semantics for them. +As far as I know, additive features are the only reasonable core semantics, so we have no choice but to "pre-process" away negative features before they ruin our core model. + +Here is an example of such a pre-processing step. +Recall from our preliminary theory section that feature sets are feature *downsets*. +Whatever the user writes, we must complete it with the missing features implied by what they wrote. +That means we have this process: + +> Syntactic feature set +> +> --- fill in missing features ---> +> +> Semantic feature downset + +We can add a middle step to account for "negative features" + +> Syntactic feature "dual set" +> +> --- negate negative features: add if they were not included, remove if they were ---> +> +> Strictly positive feature set +> +> --- fill in missing features ---> +> +> Semantic feature downset + +But not the ramifications of this: the final "fill in missing features" step may well "add back" one of the features that was removed! + +I think this will be confusing to users, to say the least. +Moreover it is crucial to understand the underlying additive feature model to become proficient with Cargo, and the more we "disguise" it with superficial negative features, the harder it will be for users to understand that model. +The syntax *impedes* learning. + +I think this is an awkward middle ground between this (dirt easy) and full feature migrations. +Only full feature migrations provide the "ideal" naming of feature so users new to a library can be blissfully ignorant of whatever features previous versions of the library supported. + # Prior art [prior-art]: #prior-art -This is a well-known problem. -See just-rejected [#3283](https://github.com/rust-lang/rfcs/pull/3283), -and my previous retracted [#3146](https://github.com/rust-lang/rfcs/pull/3146). - -I think this is much simpler than the other two. +Nothing direct to my knowledge. +In Haskell we often implement a lot of "non-empty" data structures because their sneaky semantics are useful. +So in some sense the Math is newly-applied here, but not newly applied to programming in general. # Unresolved questions [unresolved-questions]: #unresolved-questions From fcf2cc55d1e46443c210cf82b94d0518c407c09f Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 12 Nov 2022 12:12:07 -0500 Subject: [PATCH 7/9] at-least-one-feature: Mention additional problem with feature migrations --- text/0000-at-least-one-feature.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index 8a98275ae2e..e87aea1aa7a 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -212,11 +212,15 @@ We can instead This works and allows giving things the "right" names" every time, but is much work work to implement. -I think it might make sense to do this someday, but it is better to start with this. +One [point brought up in the comments](https://github.com/rust-lang/rfcs/pull/3146#issuecomment-1273473456) is that punning on the lower version bound to get the feature namespace is a bit tricky. +In particular, it makes manually adjusting versions bounds risky because without consulting package definitions it is unclear how the feature list will be interpretted. +I think that is compelling reason not to do that, but instead version the feature namespace separately. + +Overal, I think it might make sense to do some sort of "name indirection" along these lines (but addressing the above problem), but it is better to start with this RFC before getting to that. My thinking about this is basically "walk before run". Today, that would be lots of work for an obscure problem, and a solution that downstream crates need to know about because it affects how dependencies are written. However if we do this first, "opt-out features" are poised to become much more popular now that they are no longer a compatibility hazard. -We can evaluate both that new popularity, and the incidence of the "bad name" problem in *practice*, and use that to justify a more heavyweight solutions. +We can evaluate both that new popularity, and the incidence of the "bad name" problem in *practice*, and use that to justify or not justify a more heavyweight solutions. ## RFC [#3283](https://github.com/rust-lang/rfcs/pull/3283) From bfc310511ed133d085a15e590b9198e70b73bbaa Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 12 Nov 2022 12:33:09 -0500 Subject: [PATCH 8/9] `at-least-one-feature = true` -> `empty-features = false` --- text/0000-at-least-one-feature.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index e87aea1aa7a..c2efdfe1784 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -59,7 +59,7 @@ The simple solution is just to rule out that problem entirely! Packages with ```toml [package] -at-least-one-feature = true +empty-features = false ``` are easier to maintain! You don't need to worry about the `no-default-features = true, features = []` case anymore. @@ -103,7 +103,7 @@ bar = ["foo"] # no need to add "baz" because "bar" picks it up Depending on a ```toml [package] -at-least-one-feature = true +empty-features = false ``` crate with an empty feature set is disallowed and invalidates the solution. The `default` feature counts as a member of that set when `default-features = true`. @@ -139,12 +139,12 @@ When we disallow the empty feature set, we are replacing P_ω with the "free joi We are enriching features with the ∨ binary operator but no ⊥ identity element. There is no empty downset becomes empty downset constraint, and thus we are free to add new features below all the others all we want. -# Compatibility of `at-least-one-feature = true` itself +# Compatibility of `empty-features = false` itself -At first, it seems like adding `at-least-one-feature = true` to a new version of a crate is a breaking change. +At first, it seems like adding `empty-features = false` to a new version of a crate is a breaking change. But, I don't think it is. We have to step back a bit: a breaking change is one that if it *didn't* come with an increasing major version, would result in valid Cargo plans that do not build. -Yes, adding `at-least-one-feature = true` to a newer version of a crate will result in depending (not dependent) crate that do not specify a feature for that dependency being unable to upgrade. +Yes, adding `empty-features = false` to a newer version of a crate will result in depending (not dependent) crate that do not specify a feature for that dependency being unable to upgrade. But that's it! Those crates will *not* have their dependencies upgraded incorrectly, resulting in a build failure, and thus there is no problem. @@ -233,7 +233,7 @@ The fact that there is always one "feature base" is just another way of accompli restriction. The main difference is that `default-features = false` is ret-conned as a feature to allow for existing users. -That can be thought of from the perspective of this RFC as a "one-off" feature migration to get reverse dependencies predating the use of `at-least-one-feature = true` on to a feature so they retroactively abide by the "at least one feature" rule. +That can be thought of from the perspective of this RFC as a "one-off" feature migration to get reverse dependencies predating the use of `empty-features = false` on to a feature so they retroactively abide by the "at least one feature" rule. ## "Negative features" From 9e61631b5bb02e457f12929e7fde64d01be2f3f7 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Sat, 12 Nov 2022 12:49:34 -0500 Subject: [PATCH 9/9] at-least-one-feature: Remove dim view --- text/0000-at-least-one-feature.md | 1 - 1 file changed, 1 deletion(-) diff --git a/text/0000-at-least-one-feature.md b/text/0000-at-least-one-feature.md index c2efdfe1784..ad5e250f7df 100644 --- a/text/0000-at-least-one-feature.md +++ b/text/0000-at-least-one-feature.md @@ -237,7 +237,6 @@ That can be thought of from the perspective of this RFC as a "one-off" feature m ## "Negative features" -I take a pretty dim view of this. It is easy to say that one wants negative features; it is harder to actually give a proper semantics for them. As far as I know, additive features are the only reasonable core semantics, so we have no choice but to "pre-process" away negative features before they ruin our core model.