Skip to content

Conversation

Lencerf
Copy link

@Lencerf Lencerf commented Jul 30, 2025

Thanks for the pull request 🎉!
Please read the contribution guide: https://doc.crates.io/contrib/.

What does this PR try to resolve?

This PR fixes a bug for the nightly feature bindeps. Basically, if

  • a package foo has an artifact dependency artifact with a specified target TARGET_ARTIFACT different from host TARGET_HOST,
  • artifact depends on proc macro macro,
  • macro conditionally depends on arch on TARGET_HOST,

cargo build would panic on TARGET_HOST with the following error message:

did not find features for (PackageId { name: "arch", version: "0.0.1", source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/arch" }, ArtifactDep(CompileTarget { name: "x86_64-apple-darwin" })) within activated_features:
[
    (
        PackageId {
            name: "foo",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo",
        },
        NormalOrDev,
    ),
    (
        PackageId {
            name: "macro",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/macro",
        },
        ArtifactDep(
            CompileTarget {
                name: "x86_64-apple-darwin",
            },
        ),
    ),
    (
        PackageId {
            name: "artifact",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/artifact",
        },
        ArtifactDep(
            CompileTarget {
                name: "x86_64-apple-darwin",
            },
        ),
    ),
]

Similar panic happens when

  • a package foo has an artifact dependency artifact with a specified target TARGET_ARTIFACT different from host TARGET_HOST,
  • artifact has a build dependency builder,
  • builder conditionally depends on arch on TARGET_HOST.

From the above message, it is clear that proc macro macro was wrongly associated with FeaturesFor::ArtifactDep instead of FeaturesFor::HostDep. Package arch was later ignored because cargo thought macro should be built for TARGET_ARTIFACT (x86_64-apple-darwin), while arch was conditionally needed on TARGET_HOST (aarch64-apple-darwin).

Similar analyses apply to the other test case.

This commit fixes 2 paths:

  • when resolving features, if we encounter build dependencies or proc macros, always associate them with FeaturesFor::HostDep.
  • when deriving UnitFor for dependencies, stop propagating artifact_target_for_features if the the dependency is a build dependency or a proc macro.

How to test and review this PR?

This PR contains 2 commits

  • the first commit adds 2 test cases to reproduce the issue above. Since they cannot pass now, they are marked with #[should_panic]
  • the second commit fixes the bug and removes the #[should_panic] from the 2 test cases.

cargo test can pass on each commit.

Lencerf added 2 commits July 30, 2025 00:53
Add 2 test cases to reproduce a bug of `-Zbindeps`.

Basically, if

- a package `foo` has an artifact dependency `artifact` with a specified
  target TARGET_ARTIFACT different from host TARGET_HOST,
- `artifact` depends on proc macro `macro`,
- `macro` conditionally depends on `arch` on TARGET_HOST,

cargo build would panic on TARGET_HOST with the following error message:

```
did not find features for (PackageId { name: "arch", version: "0.0.1", source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/arch" }, ArtifactDep(CompileTarget { name: "x86_64-apple-darwin" })) within activated_features:
[
    (
        PackageId {
            name: "foo",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo",
        },
        NormalOrDev,
    ),
    (
        PackageId {
            name: "macro",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/macro",
        },
        ArtifactDep(
            CompileTarget {
                name: "x86_64-apple-darwin",
            },
        ),
    ),
    (
        PackageId {
            name: "artifact",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/artifact",
        },
        ArtifactDep(
            CompileTarget {
                name: "x86_64-apple-darwin",
            },
        ),
    ),
]
```

Similar panic happens when

- a package `foo` has an artifact dependency `artifact` with a specified
  target TARGET_ARTIFACT different from host TARGET_HOST,
- `artifact` has a build dependency `builder`,
- `builder` conditionally depends on `arch` on TARGET_HOST.

Signed-off-by: Changyuan Lyu <[email protected]>
…uild deps

As reproduced in the 2 fixed test cases of this commit, cargo panicked
when

- a package `foo` has an artifact dependency `artifact` with a specified
  target TARGET_ARTIFACT different from host TARGET_HOST,
- `artifact` depends on proc macro `macro`,
- `macro` conditionally depends on `arch` on TARGET_HOST,

with the follwing message

```
did not find features for (PackageId { name: "arch", version: "0.0.1", source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/arch" }, ArtifactDep(CompileTarget { name: "x86_64-apple-darwin" })) within activated_features:
[
    (
        PackageId {
            name: "foo",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo",
        },
        NormalOrDev,
    ),
    (
        PackageId {
            name: "macro",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/macro",
        },
        ArtifactDep(
            CompileTarget {
                name: "x86_64-apple-darwin",
            },
        ),
    ),
    (
        PackageId {
            name: "artifact",
            version: "0.0.1",
            source: "/Users/lencerf/Developer/cargo/target/tmp/cit/t0/foo/artifact",
        },
        ArtifactDep(
            CompileTarget {
                name: "x86_64-apple-darwin",
            },
        ),
    ),
]
```

From the above message, it is clear that proc macro `macro` was wrongly
associated with `FeaturesFor::ArtifactDep` instead of
`FeaturesFor::HostDep`. Package `arch` was later ignored because cargo
thought `macro` should be built for TARGET_ARTIFACT
(x86_64-apple-darwin), while `arch` was conditionally needed on
TARGET_HOST (aarch64-apple-darwin).

Similar analyses apply to the other test case.

This commit fixes 2 paths:
- when resolving features, if we encounter build dependencies or proc
  macros, always associate them with `FeaturesFor::HostDep`.
- when deriving UnitFor for dependencies, stop propagating
  artifact_target_for_features if the the dependency is a build
  dependency or a proc macro.

Signed-off-by: Changyuan Lyu <[email protected]>
@rustbot
Copy link
Collaborator

rustbot commented Jul 30, 2025

r? @weihanglo

rustbot has assigned @weihanglo.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot rustbot added A-dependency-resolution Area: dependency resolution and the resolver A-features2 Area: issues specifically related to the v2 feature resolver A-profiles Area: profiles S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 30, 2025
@Lencerf
Copy link
Author

Lencerf commented Jul 30, 2025

This PR should fix #12358 too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-dependency-resolution Area: dependency resolution and the resolver A-features2 Area: issues specifically related to the v2 feature resolver A-profiles Area: profiles S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants