fix(bindeps): target field specified and optional = true coexist

> Adapted from #11183

Previously, `is_dep_activated` depends on `activated_dependencies`,
which is a map of `PackageFeaturesKey` to its own activated `DepFeature`s.
`PackageFeaturesKey` in feature resolver is always comprised of

* A `PackageId` of a given dependency, and
* A enum value that helps decoupling activated features for that dependency.
  Currently depending on the type of given dependency.

Looking into issue 10526, it has an `activated_dependencies` of

```
{
    (mycrate, NormalOrDev) -> [dep:mybindep]
}
```

However, this [line][1] accidentally use a parent's `pkgid`
and a dependency's `FeaturesFor` to compose a key:

```
(mycrate, ArtifactDep("x86_64-unknown-linux-gnu"))
```

That is never a valid key to query features for artifacts dependency.
A valid key should be comprised of components both from the parent:

```
(mycrate, NormalOrDev)
```

Or both from the dependency itself:

```
(mybindep, ArtifactDep("x86_64-unknown-linux-gnu"))
```

This `unit_for` is from parent and should already contain its own
artifact dep information inside `artifact_target_for_features`,
so we don't need to map any dependency artifact from `dep.artifact()`.

[1]: a2ea66bea6/src/cargo/core/compiler/unit_dependencies.rs (L1106-L1107)
This commit is contained in:
Weihang Lo 2022-11-28 13:59:57 +00:00
parent 7dcb6daa7d
commit bf56587e26
No known key found for this signature in database
GPG key ID: D7DBF189825E82E7
2 changed files with 7 additions and 5 deletions

View file

@ -1103,7 +1103,7 @@ impl<'a, 'cfg> State<'a, 'cfg> {
// If this is an optional dependency, and the new feature resolver
// did not enable it, don't include it.
if dep.is_optional() {
let features_for = unit_for.map_to_features_for(dep.artifact());
let features_for = unit_for.map_to_features_for(None);
if !self.is_dep_activated(pkg_id, features_for, dep.name_in_toml()) {
return false;
}

View file

@ -2345,7 +2345,6 @@ fn calc_bin_artifact_fingerprint() {
#[cargo_test]
fn with_target_and_optional() {
// This is a incorrect behaviour got to be fixed.
// See rust-lang/cargo#10526
if cross_compile::disabled() {
return;
@ -2386,12 +2385,15 @@ fn with_target_and_optional() {
p.cargo("check -Z bindeps -F d1 -v")
.masquerade_as_nightly_cargo(&["bindeps"])
.with_stderr_contains(
.with_stderr(
"\
[ERROR] environment variable `CARGO_BIN_FILE_D1` not defined
[COMPILING] d1 v0.0.1 [..]
[RUNNING] `rustc --crate-name d1 [..]--crate-type bin[..]
[CHECKING] foo v0.0.1 [..]
[RUNNING] `rustc --crate-name foo [..]--cfg[..]d1[..]
[FINISHED] dev [..]
",
)
.with_status(101)
.run();
}