-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New namespaced features implementation. #8799
Conversation
r? @Eh2406 (rust_highfive has picked a reviewer for you, use r? to override) |
This was clearly a lot of work. Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! 🎉
Just one suggestion.
src/doc/src/reference/unstable.md
Outdated
a feature of the same name as a dependency is defined, that feature must | ||
include the dependency as a requirement, as `foo = ["crate:foo"]`. | ||
[features] | ||
serde = ["crate:serde", "bigdecimal/serde", "chrono/serde", "num-bigint/serde"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As per what you mentioned in the test crate_feature_with_explicit
, I think it's a little bit ambiguous on what happens if I define a feature bigdecimal = []
. Can we disallow bigdecimal/serde
in that case and complain about it? And then we can suggest users to use crate:bigdecimal/serde
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not entirely clear about what is ambiguous. bigdecimal = []
defines a feature named bigdecimal
. If you specify bigdecimal/serde
, it enables the bigdecimal
crate (if it is optional), enables the serde
feature on bigdecimal
, and enables the bigdecimal
feature. I don't think we can disallow that since that is the current behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great, thanks again for working on this! I've left a few nits here and there but otherwise I think this is basically ready to go
src/cargo/core/resolver/features.rs
Outdated
let fv = FeatureValue::Crate(*dep_name); | ||
let fv = FeatureValue::Crate { | ||
dep_name: *dep_name, | ||
// explicit: *explicit, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leftover?
src/cargo/core/summary.rs
Outdated
dep_feature: InternedString, | ||
/// If this is true, then the feature used the `crate:` prefix, which | ||
/// prevents enabling the feature named `dep_name`. | ||
explicit: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The term explicit
here seemed a bit confusing to me given this documentation of what it means, perhaps something like crate_prefix
or something like that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds better, thanks!
src/cargo/core/summary.rs
Outdated
Crate(ref c) => { | ||
if s.namespaced_features() { | ||
format!("crate:{}", &c) | ||
let (dep, explicit) = if dep.starts_with("crate:") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think strip_prefix
is a stable thing to use now?
Package::new("baz", "1.0.0").publish(); | ||
Package::new("bar", "1.0.0") | ||
.add_dep(Dependency::new("baz", "1.0").optional(true)) | ||
.feature("feat", &["crate:baz"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a reminder to us, crates.io probably rejects this syntax today in the frontend so we'll likely need to update that to publish packages like this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. I'm actually not sure how to roll this out, since we'll need to be pretty confident on the design since it affects the index. At what point do we decide to turn it on?
To avoid confusion with the...other thing called "features".
I'm not sure why the original code partitioned the errors in the way that it did. I think it is better to exhaustively match all the reasons, so that when new reasons are added, it will be clear that this code needs to be updated. I also think it simplifies the code a little.
I'm moved by the argument from @est31 that I have pushed a commit that renames it to |
@bors: r+ I think it's a good point that I'm going to go ahead and r+ since this is all unstable anyway, and we can continue to tweak it. Otherwise what's here looks great, thanks @ehuss! |
📌 Commit f4ac82a has been approved by |
☀️ Test successful - checks-actions |
Thanks for fixing this stuff up, sorry I wasn't able to get to it sooner. |
Fix publishing with optional dependencies. In #8799, I neglected to update the `publish` code to use the correct features when generating the JSON to upload to the registry. The `Cargo.toml` file was correctly updated, but the JSON was not. This caused Cargo to send the implicit `dep:` feature syntax in the JSON blob, which crates.io rejects. The solution here is to use the original feature map before the implicit features have been added.
Fix publishing with optional dependencies. In rust-lang#8799, I neglected to update the `publish` code to use the correct features when generating the JSON to upload to the registry. The `Cargo.toml` file was correctly updated, but the JSON was not. This caused Cargo to send the implicit `dep:` feature syntax in the JSON blob, which crates.io rejects. The solution here is to use the original feature map before the implicit features have been added.
This is a new implementation for namespaced features (#5565). See the
unstable.md
docs for a description of the new behavior. This is intended to fix several issues with the existing design, and to make it backwards compatible so that it does not require an opt-in flag.This also includes tangentially-related changes to the new feature resolver. The changes are:
crate_name/feat_name
syntax will now always enable the featurecrate_name
, even if it is an inactive optional dependency (such as a dependency for another platform). The intent here is to have a certain amount of consistency whereby "features" are always activated, but individual crates will still not be activated.--all-features
will now enable features for inactive optional dependencies. This is more consistent with--features foo
enabling thefoo
feature, even when thefoo
dep is not activated.I'm still very conflicted on how that should work, but I think it is better from a simplicity/consistency perspective. I still think it may be confusing if someone has a
cfg(some_dep)
in their code, andsome_dep
isn't built, it will error. The intent is thatcfg(accessible(some_dep))
will be the preferred method in the future, or using platformcfg
expression likecfg(windows)
to match whatever is in Cargo.toml.Closes #8044
Closes #8046
Closes #8047
Closes #8316
Questions
For various reasons, I changed the way dependency conflict errors are collected. One slightly negative consequence is that it will raise an error for the first problem it detects (like a "missing feature"). Previously it would collect a list of all missing features and display all of them in the error message. Let me know if I should retain the old behavior. I think it will make the code more complicated and brittle, but it shouldn't be too hard (essentially
Requirements
will need to collect a list of errors, and thenresolve_features
would need to check if the list is non-empty, and then aggregate the errors).Should
cargo metadata
show the implicit features in the "features" table? Currently it does not, and I think that is probably best (it mirrors what is inCargo.toml
), but I could potentially see an argument to show how cargo sees the implicit features.