Skip to content

Conversation

@Lencerf
Copy link
Contributor

@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.

@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
Contributor Author

Lencerf commented Jul 30, 2025

This PR should fix #12358 too.

@Lencerf
Copy link
Contributor Author

Lencerf commented Nov 19, 2025

Hi @weihanglo , it has been a few months, do you have any feedbacks on this PR? Thank you!

@weihanglo
Copy link
Member

Oops. It completely slipped off my radar 😅. I'll find some time to review it this week. Sorry for the huge delay

Copy link
Member

@weihanglo weihanglo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Looks pretty good to me. And sorry for the extremely long delay 🙇🏾‍♂️.

View changes since this review

} else {
self.panic_setting
};
let artifact_target_for_features =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a simple comment here explaining why we clearing the marker here? Like build.rs itself (not build-deps) and proc macros are always for host.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

r#"pub fn add(a: i32, b: i32) -> i32 { a + b }"#,
)
.build();
p.cargo("test -Z bindeps")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mind adding with_stderr_data(str![[""]]) to ensure that we really build arch? Ditto for proc macro test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you'll need to set env SNAPSHOTS=overwrite to regenerate test snapshot locally and commit it btw

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @Lencerf!

https://github.com/rust-lang/cargo/actions/runs/19524318318/job/55893849063?pr=15788#step:15:4772

I know it is annoying, but we also need to append [EXE] for binary paths for windows compatibility

- [RUNNING] unittests src/main.rs (target/debug/deps/foo-[HASH])
+ [RUNNING] unittests src/main.rs (target/debug/deps/foo-[HASH][EXE])

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback! CI now passes!

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]>
@rustbot
Copy link
Collaborator

rustbot commented Nov 20, 2025

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

…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 following 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]>
Copy link
Member

@weihanglo weihanglo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix!

View changes since this review

@weihanglo weihanglo added this pull request to the merge queue Nov 20, 2025
Merged via the queue into rust-lang:master with commit b5b8b07 Nov 20, 2025
26 checks passed
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 20, 2025
bors added a commit to rust-lang/rust that referenced this pull request Nov 22, 2025
Update cargo submodule

7 commits in 5c0343317ce45d2ec17ecf41eaa473a02d73e29c..9fa462fe3a81e07e0bfdcc75c29d312c55113ebb
2025-11-18 19:05:44 +0000 to 2025-11-21 20:49:51 +0000
- Enable CARGO_CFG_DEBUG_ASSERTIONS in build scripts based on profile (rust-lang/cargo#16160)
- fix(config-include): disallow glob and template syntax (rust-lang/cargo#16285)
- test(config-include): include always relative to including config (rust-lang/cargo#16286)
- docs(guide): When suggesting alt dev profile, link to related issue (rust-lang/cargo#16275)
- refactor(timings): separate data collection and presentation (rust-lang/cargo#16282)
- test(build-std): Add test for LTO (rust-lang/cargo#16277)
- fix(bindeps): do not propagate artifact dependency to proc macro or build deps (rust-lang/cargo#15788)

r? ghost
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

Projects

None yet

3 participants