-
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
v2 resolver: different handling for inactive, optional dependencies based on how they're specified #8316
Comments
Unfortunately the commit bce9ea7e6150049a8e660b401b7dabf79f8abdef is no longer available on any branch in your repository. Would it be possible to create a branch with this reproduction? I tried manually updating the x86-active branch, but I couldn't reproduce the problem. |
@ehuss could you try with the |
I guess maybe I'm a little confused. If I:
I get the same output for the I can see how the difference between having a feature |
Thanks! The main difference between the v1 and v2 resolvers is that inactive targets are always enabled for the v1 resolver so the issue is moot there. So in other words, on x86_64, here's the table for if the
Thinking about it more, you're probably right -- for the v2 resolver both columns should probably read "disabled". |
@ehuss do you think this would be fixable before the v2 resolver is stabilized? or would fixing this after stabilization not be considered a breaking change. |
Yep, I think this should definitely be fixed before stabilization. I'm not sure how likely it is to break anything, but better to be safe. If you want to try to fix it, feel free to dive in! Otherwise, it might be a while since I need to work on #8549 first, and it is going to be challenging. I have put together an update to the existing testsuite to cover this situation and exhibits the undesired behavior: diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs
index 3790ab4be..54a0ffd71 100644
--- a/tests/testsuite/features2.rs
+++ b/tests/testsuite/features2.rs
@@ -96,6 +96,7 @@ fn inactive_target_optional() {
[features]
foo1 = ["dep1/f2"]
+ foo2 = ["dep2"]
"#,
)
.file(
@@ -103,6 +104,7 @@ fn inactive_target_optional() {
r#"
fn main() {
if cfg!(feature="foo1") { println!("foo1"); }
+ if cfg!(feature="foo2") { println!("foo2"); }
if cfg!(feature="dep1") { println!("dep1"); }
if cfg!(feature="dep2") { println!("dep2"); }
if cfg!(feature="common") { println!("common"); }
@@ -149,7 +151,7 @@ fn inactive_target_optional() {
.build();
p.cargo("run --all-features")
- .with_stdout("foo1\ndep1\ndep2\ncommon\nf1\nf2\nf3\nf4\n")
+ .with_stdout("foo1\nfoo2\ndep1\ndep2\ncommon\nf1\nf2\nf3\nf4\n")
.run();
p.cargo("run --features dep1")
.with_stdout("dep1\nf1\n")
@@ -164,9 +166,10 @@ fn inactive_target_optional() {
.with_stdout("common\nf4\n")
.run();
+ // ERROR: This fails with "dep2" feature enabled.
p.cargo("run -Zfeatures=itarget --all-features")
.masquerade_as_nightly_cargo()
- .with_stdout("foo1\n")
+ .with_stdout("foo1\nfoo2\n")
.run();
p.cargo("run -Zfeatures=itarget --features dep1")
.masquerade_as_nightly_cargo() |
@sunshowers If you have something like this: [target.'cfg(not_my_platform)'.dependencies]
log = { version = "0.4", optional = true } and you ran |
@ehuss (sorry for the late response, I had to be away for a while and then I missed your q...) Hmm, code that uses it would probably be like:
If the |
BTW, following up here, I did some more tests against
This is a bit different from what we discussed above (both lines for |
Looks like rust-lang/cargo#8316 has been addressed upstream in a way that's at least self-consistent, and our simulations match it already.
Looks like rust-lang/cargo#8316 has been addressed upstream in a way that's at least self-consistent, and our simulations match it already.
We (the team) had some long discussions about this, and decided to go with that behavior, particularly when considering namespaced features. By decoupling features with dependencies, that means that a feature gets enabled, even if one of its dependencies is not. So for example, an optional dependency creates an implicit feature like this: [features]
somedep = ["dep:somedep"] Here, if "dep:somedep" is deactivated, the feature is still set. Making the feature disappear if its dep is deactivated would introduce an inconsistency with how other features behave. It could also cause some complications with more complex features like I realize it may cause some confusion in some cases if someone does I thought I had included this in the new documentation, but I see I missed it. |
Ahh, that makes sense in the context of namespaced features. Thanks. |
(reopening in case you want to close it after documenting) |
Problem
Looks like the v2 resolver appears to have some small differences to a dependency that's optional, target-specific, and currently inactive, based on how it's specified.
Specifically, if
inactive
is a target-specific, optional dependency that is inactive on the platform under consideration:causes the
inactive
feature to not be activated, whiledoes cause the feature to be activated.
Steps
Test workspace.
causes:
Now if you change to:
You'll get:
There is no difference between the two for active features, as you can find out by setting
--target i686-unknown-linux-gnu
.Possible Solution(s)
A uniform solution for both, I'd prefer the
x86-active
feature to be present for both I think.Notes
Output of
cargo version
:cc @ehuss
The text was updated successfully, but these errors were encountered: