-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Stabilize Cargo's new feature resolver #2957
Conversation
cc @rust-lang/cargo |
At the moment my-feature = ["my-optional-dependency/their-feature"] also enables an optional dependency when So I feel like the new resolver should also not automatically enable optional dependencies just because a feature got delegated. Otherwise I feel like this may be something that would go into an eventual resolver version 3 in some way. |
@CryZe I recognize that the inability to conditionally enable features on optional dependencies makes it difficult or impossible to express certain things. That request is tracked in rust-lang/cargo#3494. There are likely several ways that can be added without breaking current behavior. Possibly through new syntax, something like namespaced features, or automatic features. Part of the goal is to avoid highly disruptive changes, and I suspect changing the meaning of Finally, we recognize that there are a large number of items on the wish list for changes to features. However, I would prefer to avoid blocking progress for changes that are not on the horizon. |
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.
Thanks to @ehuss for all the work to make this happen! Overall I love the improvements!
text/0000-cargo-features2.md
Outdated
|
||
Testing has been performed on various projects that shows sometimes | ||
dependencies are written to assume that features from another part of the | ||
graph are enabled, and fail to compile with the new resolver. Because the new |
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.
It took me a few tries to parse this sentence. Maybe it can be broken up something like "Testing has been performed on various projects. Some whur found to fail to compile with the new resolver. Witch shows that sometimes dependencies are written to assume that features from another part of the graph are enabled."
text/0000-cargo-features2.md
Outdated
Setting the resolver to `"2"` switches Cargo to use the new feature resolver. | ||
It also enables backwards-incompatible behavior detailed in [New command-line | ||
behavior](#new-command-line-behavior). `"2"` is the only valid option, if | ||
`resolver` is not specified then the old behavior is used. |
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.
Is there any reason why resolver = "1"
is not something we are going to accept, even if just for reduced surprise factor? (As a prior art --edition
accepts both 2018 and 2015 as a value)
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.
There isn't a strong reason, just a personal preference of not wanting to see resolver = "1"
being used, but it can be easily added.
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 we should add this, so that if we want to change the default for resolver
at a later date (maybe a new rust edition etc..)
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.
@pksunkara That assumes we want to support using a new edition but opting for the old resolver, which I don't know that we want to support. We could minimize the matrix of simultaneously supported features by not supporting the old resolver on a new edition that implies the new resolver.
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 @ehuss! Can't wait to see this happen, this will help immensely in the embedded ecosystem ❤️
text/0000-cargo-features2.md
Outdated
|
||
Note that this is a global decision. So a command like `cargo build | ||
--all-targets` will include examples and tests, and thus features from | ||
dev-dependencies will be enabled. |
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.
Does this mean that doing cargo build --lib
followed by cargo build --all-targets
will potentially recompile a lot of the dependency graph if a new feature is turned on?
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.
Yes, that is possible.
text/0000-cargo-features2.md
Outdated
[package] | ||
name = "my-package" | ||
version = "1.0.0" | ||
resolver = "2" |
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.
Incredibly nitpicky, but why the string "2"
instead of the number 2?
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 intent is to keep it a free-form string for future additions, like enabling different options. Hopefully that won't be necessary, but I wanted to leave it flexible.
text/0000-cargo-features2.md
Outdated
* This adds complexity to Cargo, and adds boilerplate to `Cargo.toml`. It can | ||
also be confusing when switching between projects that use different | ||
settings. It is intended in the future that new resolver will become the | ||
default via the "edition" declaration. This will remove the extra |
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.
edition
is a non-global choice and therefore workspaces generally do not have the edition annotation. Does this mean that workspaces are doomed to forever using resolver
annotation and/or using the old resolver?
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.
We are planning to add the edition
field to the [workspace]
table. That is still a bit up in the air, since we haven't really defined what that will do (would it be the default for all workspace members?). Issue rust-lang/cargo#5784 is tracking that. One of my concerns is that with RFC 2906, that inheriting package metadata will require specifying { workspace = true }
and that ends up creating more boilerplate in each package. But making it implicitly inherit the edition would be inconsistent with the other fields.
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.
Excellent work!
I think scoping this to dev/target/host deps, and deferring workspace unification is a good call.
text/0000-cargo-features2.md
Outdated
[dev-dependencies](#dev-dependencies), the general rule is, if a dependency is | ||
not built, it does not affect feature resolution. For [host | ||
dependencies](#host-dependencies), the general rule is that packages used for | ||
building (like proc-macros) do not affect the packages being built. |
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.
Might be a good idea again to explicitly mention that workspace feature unification is deffered to future work, it took me a couple of reads to find out if this is in scope for the RFC.
This looks great! Minor nit: I wonder about the choice to use a string for the resolver value in the manifest. Couldn't that be an integer instead? What ideas went into deciding it should be a string? |
@djc That is answered above here: #2957 (comment) |
@ehuss because multiple people have asked the same, maybe it should be written explicitly in the RFC under "Future possibilities":
|
text/0000-cargo-features2.md
Outdated
|
||
* Features for individual packages can be enabled by using | ||
`member_name/feature_name` syntax. For example, `cargo build --workspace | ||
--feature member_name/feature_name` will build all packages in a workspace, |
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 am assuming that we can do cargo build -p member1 -p member2 --features member1/foo
. Would be a good idea expanding how usage in this item interacts with the usage in the above item.
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 sure what kind of expansion you are looking for. It enables the feature foo
on the package member1
. You can also experiment with -Zpackage-features
on nightly to see how it behaves.
text/0000-cargo-features2.md
Outdated
Feedback on desired use cases for feature information will help define the | ||
solution. A possible alternative is to stabilize the [`--unit-graph`] flag, | ||
which exposes Cargo's internal graph structure, which accurately indicates the | ||
actual dependency relationships and uses the new feature resolver. |
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 am not sure how unit-graph
's output looks like, but I want to say that cargo metadata
and https://lib.rs/crates/cargo_metadata is used by a lot of projects in the ecosystem. I reckon we need to look into fixing this when this new resolver is implemented.
IIRC even rust-analyzer depends on it to understand the dependency graph. /cc @matklad
This looks awesome! Great work @ehuss. I have a major concern that is not addressed in the RFC though. How will this interact with #2887 (artifact dependencies) or other future plans like that? I can kinda understand how the resolver works and can extrapolate the behaviour, but I would still like to see this specifically talked about. |
The RFC explicitly calls out the future concerns in the Future possibilities section, and in Drawbackes section, which mentions that future changes may require opting in to new behavior with the I don't think it is feasible to design every potential enhancement that may come in the future and understand how they might interact. Some work along those lines has been done (see rust-lang/cargo#8799 and rust-lang/cargo#8818), but if this RFC is delayed until everything is considered, it will never be stabilized. The onus is on those future enhancements to consider how they integrate into the existing behaviors and environment. |
I've pushed some small updates to clarify some things. I'd like to nudge this along, so: @rfcbot fcp merge @rust-lang/cargo I believe this is in a state to be stabilized. The only open issue I am concerned about is rust-lang/cargo#8312 (I added a summary in the RFC), but there is no clear solution to me. I am uncertain how likely it is to cause problems (there haven't been any real-world reports so far). It may be possible that we can tweak the behavior later if it becomes evident that it is a real problem. |
Team member @ehuss has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
This is a clear improvement and the nightly implementation has been widely appreciated. So: At some point we should think if a future rewrite of the dependency resolver (pubgrub-rs) can become aware of and incorporate some of this logic. But the current feature resolver is working and will work with a rewrite, so there is no reason to hold up this on that. |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
219d2c2
to
66905a8
Compare
Thanks everyone for the comments! I have posted rust-lang/cargo#8997 to follow through with the stabilization. |
Stabilize -Zfeatures and -Zpackage-features. This follows through with [RFC 2957](rust-lang/rfcs#2957) to stabilize the new feature resolver, and `-Zpackage-features` command-line changes. This also rewrites the "Features" chapter to try to expand it a little. I decided to leave the `-Zfeatures` flag in for now for testing, but it can be removed at a later date. There is a code change related to the `package-name/feature-name` syntax for the `--features` flag. I wanted to stabilize that for `resolver = "1"`, but I previously neglected to separate that behavior out, so it required change to `Workspace::members_with_features` to make that work (see the `resolver1_member_features` test). Closes #4328 Closes #5364 Closes #7914 Closes #7915 Closes #7916 Closes #8088 Closes #8431
This RFC proposes to stabilize Cargo's new feature resolver, and the new command-line behavior for feature flags.
Rendered