-
Notifications
You must be signed in to change notification settings - Fork 2.6k
implement package feature unification #15684
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
base: master
Are you sure you want to change the base?
Conversation
r? @weihanglo rustbot has assigned @weihanglo. Use |
ad48f18
to
e94564d
Compare
@@ -1860,7 +1860,7 @@ Specify which packages participate in [feature unification](../reference/feature | |||
* `selected`: Merge dependency features from all packages specified for the current build. | |||
* `workspace`: Merge dependency features across all workspace members, | |||
regardless of which packages are specified for the current build. | |||
* `package` _(unimplemented)_: Dependency features are considered on a package-by-package basis, | |||
* `package`: Dependency features are considered on a package-by-package basis, |
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 PR implements it as projects
instead of package
. What was the motivation for 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.
It was a mistake but where I got the wrong name, I really can't say. Fixed everywhere, hopefully.
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.
Would be good to have a cargo tree
test as well
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.
and cargo fix
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've added a cargo tree
test, I'll just have to fixup history so that it's added before the feature.
That said, I think it might need a bit of design work because using package
and selected
feature unification has almost identical outuput, but in the former each tree should be taken on its own while in the latter the user should be aware that the features are unified.
For example in one simplified case where a depends on common/a
and b depends on common/b
; package
outputs:
common v0.1.0 ([ROOT]/foo/common)
a v0.1.0 ([ROOT]/foo/a)
└── common feature "a"
└── common v0.1.0 ([ROOT]/foo/common)
b v0.1.0 ([ROOT]/foo/b)
└── common feature "b"
└── common v0.1.0 ([ROOT]/foo/common)
while selected
currently outputs:
a v0.1.0 ([ROOT]/foo/a)
└── common feature "a"
└── common v0.1.0 ([ROOT]/foo/common)
b v0.1.0 ([ROOT]/foo/b)
└── common feature "b"
└── common v0.1.0 ([ROOT]/foo/common)
common v0.1.0 ([ROOT]/foo/common)
and for completeness, workspace
outputs:
a v0.1.0 ([ROOT]/foo/a)
└── common feature "a"
└── common v0.1.0 ([ROOT]/foo/common)
b v0.1.0 ([ROOT]/foo/b)
└── common feature "b"
└── common v0.1.0 ([ROOT]/foo/common)
common v0.1.0 ([ROOT]/foo/common)
I'm not sure what would be the ideal behavior here though, we probably don't want to have both features coming out of both packages in selected
because people often use this to find out what package turned on a given feature. But I don't think we should keep it as is either. Maybe adding an edge that signifies a feature but somehow marks it as coming from unification elsewhere?
For example something like this?
a v0.1.0 ([ROOT]/foo/a)
└── common feature "a"
└── common v0.1.0 ([ROOT]/foo/common)
└── common feature "b" (unified)
└── common v0.1.0 ([ROOT]/foo/common)
b v0.1.0 ([ROOT]/foo/b)
└── common feature "b"
└── common v0.1.0 ([ROOT]/foo/common)
└── common feature "a" (unified)
└── common v0.1.0 ([ROOT]/foo/common)
common v0.1.0 ([ROOT]/foo/common)
Should there be some kind of proposal for these changes? And in that case should I just fixup history with the current behavior or wait for the outcome of that? Or is it fine to make the changes as part of this PR or a different one but without any larger proposal than just the PR?
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.
Should there be some kind of proposal for these changes? And in that case should I just fixup history with the current behavior or wait for the outcome of that? Or is it fine to make the changes as part of this PR or a different one but without any larger proposal than just the PR?
We can clean this up and get it merged and leave it as an Open Question on the tracking issue to have the discussion run independent of this PR
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.
Ok, tree tests are added now as well as one fix test. I did not know what to test for though so I just took a random fix test from edition 2021 to 2024 since the relevant change should break just a specific upgrade from 2018. If you want to test for something different, let me know.
src/cargo/ops/fix/mod.rs
Outdated
@@ -588,7 +588,15 @@ fn check_resolver_change<'gctx>( | |||
feature_opts, | |||
)?; | |||
|
|||
let diffs = v2_features.compare_legacy(&ws_resolve.resolved_features); | |||
if ws_resolve.specs_and_features.len() != 1 { | |||
bail!(r#"Cannot fix edition when using `feature-unification = "projects"`."#); |
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.
Cargo error messages should start with a lower case letter
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.
Fixed
src/cargo/ops/fix/mod.rs
Outdated
@@ -588,7 +588,15 @@ fn check_resolver_change<'gctx>( | |||
feature_opts, | |||
)?; | |||
|
|||
let diffs = v2_features.compare_legacy(&ws_resolve.resolved_features); | |||
if ws_resolve.specs_and_features.len() != 1 { | |||
bail!(r#"Cannot fix edition when using `feature-unification = "projects"`."#); |
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.
cargo fix - from what I understand, the location is reached only with --edition. I think it should be ok to disallow using cargo fix --edition when someone already uses this feature.
This should just be limited to projects with edition = "2018"
which should be fine
target_data, | ||
force_all_targets, | ||
)?; | ||
for specs in individual_specs { |
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.
So we're creating independent resolves for each package. I take it we can then leave merging of these graphs to a future possibility to further optimize 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.
Just independent ResolvedFeatures
, it seems everything works with just a single targeted_resolve
, though I did not expect that since the field is documeted with "The narrowed resolve, with the specific features enabled." Then from those independent unit graphs are constructed and those are then merged into a single build context.
I probably don't understand the whole process well enough, but I don't see a way to merge anything earlier?
src/cargo/ops/tree/mod.rs
Outdated
// TODO build multiple graphs, one for each resolved features set. | ||
let resolved_features = &ws_resolve |
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.
cargo tree - I just use the first feature set. This is definitely not ideal, but I'm not entirely sure what's the correct solution here. Printing multiple trees? Disallowing this, forcing users to select only one package?
I see this as no different than cargo tree --workspace
where there will be multiple root packages. --edges features
(ro whatever its called) will be needed to fully understand it.
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.
True, I got confused, this part is fine. I think that just signalling to the user whether features are unified between the trees or not is a new problem.
e94564d
to
c6090d5
Compare
Thanks for moving this forward! |
c6090d5
to
e5a3134
Compare
Feel free to edit the commits as needed |
e5a3134
to
90a6e11
Compare
b10f5d9
to
2457810
Compare
I've also just added a test with weak dependencies, which works. I tried to also add namespaced |
2457810
to
d28a30f
Compare
What does this PR try to resolve?
Implements another part of feature unification (#14774, rfc). The
workspace
option was implemented in #15157, this adds thepackage
option.How to test and review this PR?
The important change is changing
WorkspaceResolve
so it can contain multipleResolvedFeature
s. Along with that, it also needs to know which specs those features are resolved for. This was used in several other places:cargo fix
- from what I understand, the location is reached only with--edition
. I think it should be ok to disallow usingcargo fix --edition
when someone already uses this feature.cargo tree
- I just use the first feature set. This is definitely not ideal, but I'm not entirely sure what's the correct solution here. Printing multiple trees? Disallowing this, forcing users to select only one package?Based on comments in #15157 I've added tests first with
selected
feature unification and then changed that after implementation. I'm not sure if that's how you expect the tests to be added first, if not, I can change the history.I've expanded the test checking that this is ignored for
cargo install
although it should work the same way even if it is not ignored (selected
andpackage
are the same thing when just one package is selected).