-
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
Poor interaction between workspace dependencies and default-features #12162
Comments
Note: I tried a workaround of specifying |
Thanks for the detailed report! Totally understand the inconvenience. I am sorry for telling you that this is an intentional behavior for following the additive rule of Cargo features. Please see this table from this comment #11409 (comment). Changing the behavior could lead to a breakage. Besides the intentional design, do you feel anything can be documented better in this chapter in Cargo Guide? |
Thanks for linking the comment! I had searched through the various PRs and RFCs to see if this was covered, I missed that one though 🙂 Could I propose changing the behavior then? What would be the right process for this, submitting an RFC maybe? I totally understand that features within Cargo need to be additive, without this property any projects with a decent number of dependencies could fail to compile because the same crate could be depended on twice, but with conflicting feature sets, making the project impossible to compile. Because this additive property exists, having a crate opt out of a feature that the workspace enables should be entirely possible? In other words, it shouldn't cause any compilation issues? I don't believe the ability to generically opt out of a feature is needed, but without the ability to disable default features at the crate level, workspace inheritance is much less useful of a feature. Recently I worked on migrating a decently large codebase to use workspace inheritance, MaterializeInc/materialize#19375, but ran into this issue with default features. Without the ability to disable default-features at a crate level, I don't think we'll go through with this switch. Which is disappointing because having a single location to define all of our dependency versions would be super useful! Thanks for chatting about this 🙂 |
FWIW, #3126 has more discussions about the future of For proposing a change, I currently have no idea which route can fix this issue, as changing the behavior leads to another breakage. However, I think you can draft your idea here and if you can think of any transition to alleviate the potential breakage, please include them! |
I've had a growing feeling that being able to inherit things besides dependency sources was a mistake. Rarely do implementation requirements mean every package needs the same set of features, If I felt confident enough in this stance, we could move to only allow inheriting source information in the next Edition (the wording is so that the package's Edition is in control since workspaces don't have an Edition). However, I am not confident enough at this time to move in that direction. People can do it themselves (or with the help of a clippy lint) except for this issue. I wonder if what we could do on an Edition boundary is to make it so that the lack of @Muscraft thoughts? |
We talked about this in today's cargo team meeting. Its a bit unclear if we'd want to go the full way and deprecate
If we want to consider that, likely the best route is a short-term solution to this issue with a lint to discourage For a short-term solution, it would likely be to make One concern with this short-term route is that is isn't as consistent in behavior across cargo. If we deprecated We do need to recognize the cost of ecosystem churn with any of this. This would be a subtle behavior change that people would need to migrate through, both in code and in education. We'd also need to make the docs more complicated to cover the cases for each Edition. |
To summarize the proposal, quoting from @Muscraft who built this on top of the work of @ehuss in #11409
Note that |
The proposal looks good to me @epage. I'd prefer an error in scenario no. 2, since we have the freedom to do that at an edition boundary. |
Hey @epage, thanks for reconsidering this! The behavior table you listed above makes sense to me and fixes the original concerns I had. FWIW I also like the idea that workspace dependencies should only be able to inherit source information, but I think the correct long term solution is a lint guiding users away from it, instead of disallowing it entirely. An example of where it would be nice to inherit features from the workspace is when it's a performance related feature, e.g. |
I left that out because its being talked about as part of #13629 |
A way to reframe this: instead of merging a package dependency into a workspace dependency, keeping the workspace dependency's defaults, we could switch to merging a workspace dependency into a package dependency, keeping the package dependency's defaults. |
Problem
Apologies in advance if this is categorized incorrectly, I can see how this could be either a bug or feature request.
Recently introduced to Cargo is the ability to specify dependencies at the workspace level. Crates within that workspace can specify their dependencies as
{ workspace = true }
, which results in that crate inheriting the dependency from their parent workspace.With respect to features the inheritance works in a purely additive way, which I believe works well in general, but not in the case of default features.
For example say you have a workspace with two crates,
foo
andbar
, both of these crates depend ontracing
. You want to make surefoo
andbar
depend on the same version oftracing
, so you define it in your workspace and have crates inherit from it. In the cratebar
you want to disabledefault-features
fortracing
, but you cannot since when you inherit from a workspace it's in a purely additive way. The only way to disabledefault-features
inbar
is to disable it at the workspace level, this has the adverse effect of also disablingdefault-features
forfoo
. In the cratefoo
you could specifydefault-features = true
, but this feels like an anti-pattern.Scaling this example up a bit and you can better see how this is an issue. Say you have a workspace of 50 crates, 10 of which depend on
tracing
. In 1 of the 10 crates you want to disabledefault-features
, to do that it requires you to specifydefault-features = true
for the other 9, and any crates in the future that depend ontracing
.Steps
workspace.dependency
oftracing = 0.1.37
(or any other crate).foo
, add a dependency oftracing = { workspace = true }
.bar
, add a dependency oftracing = { workspace = true, default-features = false }
.bar
, indicating that thedefault-features
flag is ignored.Possible Solution(s)
Allow inherited dependencies within a workspace to disable default features.
Notes
No response
Version
The text was updated successfully, but these errors were encountered: