Skip to content

fix: ignore implicit std dependencies in unused-crate-dependencies lint#16677

Open
biscuitrescue wants to merge 4 commits intorust-lang:masterfrom
biscuitrescue:unused_crate_deps
Open

fix: ignore implicit std dependencies in unused-crate-dependencies lint#16677
biscuitrescue wants to merge 4 commits intorust-lang:masterfrom
biscuitrescue:unused_crate_deps

Conversation

@biscuitrescue
Copy link

fixes 152561

What does this PR try to solve?

Cargo explicitly passes standard library crates (core, alloc, etc.) as
extern dependencies when using -Zbuild-std, which causes "erroneous"
warnings because these crates are not listed in the user's Cargo.toml.

The working

This was initially issued on the rust repo, for which i filed a PR, using noprelude to exclude linting, but it was correctly pointed out that this was not the correct approach.
Following Zulip discussions, I added a nounused flag to the UnitDeps struct which is similar in working to the noprelude flag.
--extern nounused:foo already exists as an unstable compiler option.

How to test and review this PR?

  1. To demonstrate that the implicitly injected crates no longer trigger linting warnings, use this test command: rustup run nightly cargo test build_std_does_not_warn_about_implicit_std_deps.
  2. Verify that core, alloc, compiler_builtins do not throw unused warnings.

Currently, nounused is emitted only for implicitly injected standard library dependencies when using -Zbuild-std.

If Cargo ever gains support for explicit builtin dependencies declared by users, it may be desirable to revisit whether nounused should apply in those cases. This PR does not change behavior for explicit dependencies.

@rustbot rustbot added A-build-execution Area: anything dealing with executing the compiler S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 25, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 25, 2026

r? @ehuss

rustbot has assigned @ehuss.
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

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ehuss, @epage, @weihanglo
  • @ehuss, @epage, @weihanglo expanded to ehuss, epage, weihanglo
  • Random selection from ehuss, epage, weihanglo

@biscuitrescue
Copy link
Author

The CI failure is due to rust-src not being available. I will update the test. One thing I'm not sure of though, should this test reside instead in tests/build-std/main.rs, or is it fine as is?

@epage
Copy link
Contributor

epage commented Feb 26, 2026

The CI failure is due to rust-src not being available. I will update the test. One thing I'm not sure of though, should this test reside instead in tests/build-std/main.rs, or is it fine as is?

test/testsuite is setup to not require rust-src. The build-std tests it does have use a mock std. Everything that uses rust-src is in tests/build-std.

@epage
Copy link
Contributor

epage commented Feb 26, 2026

Note that we ask for PRs to be focused on how they should be reviewed and merged, and not how they were implemented. This includes making the commits atomic.

One twist on that is we've found it helpful to add tests in the commit before the fix, with them passing, reproducing the undesired behavior. The fix commit would then update them to show the new behavior and the diff between them shows how behavior changed.

See also https://doc.crates.io/contrib/process/working-on-cargo.html#submitting-a-pull-request

Comment on lines +6517 to +6525
p.cargo("build -Zbuild-std")
.masquerade_as_nightly_cargo(&["build-std"])
.env("RUSTFLAGS", "-W unused-crate-dependencies")
// Use .with_stderr() with a pattern to be more flexible
.with_stderr_contains("[WARNING] extern crate `bar` is unused in crate `buildstd_test`")
.with_stderr_contains("[..]unused-crate-dependencies[..]")
.with_stderr_does_not_contain("extern crate `core` is unused")
.with_stderr_does_not_contain("extern crate `alloc` is unused")
.with_stderr_does_not_contain("extern crate `compiler_builtins` is unused")
Copy link
Contributor

Choose a reason for hiding this comment

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

Normally, we try to avoid use of does_not_contain tests because the format of the output could change and then we'd never know if this regressed.

We normally use snapsnhots. How much to include needs to balance that we don't want to overly constrain rustc in the output because it makes updates to the compiler more difficult

Comment on lines +1897 to +1900
if nounused {
opts.push("nounused");
*unstable_opts = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

What does the path to stabilizing this look like?

Copy link
Contributor

Choose a reason for hiding this comment

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

I also wonder if we should start tracking all of the different unstable features of rustc build-std is relying on to not get surprised when we stabilize it.

CC @davidtwco

@epage
Copy link
Contributor

epage commented Feb 26, 2026

On a related note, I'm working on integrating this lint into Cargo so it can be properly reported, #16600. As part of this, I've posted rust-lang/rfcs#3920. I wonder if I should tie nounused into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-build-execution Area: anything dealing with executing the compiler 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.

Diags unused_crate_dependencies&unused_extern_crates "errneously" issued w/ -Z build-std

4 participants