Repository: rust
Issue: `unused_crate_dependencies` false-positives in crates with muliple (lib/bin) targets
Labels: A-lints,T-compiler,C-bug,A-crates,L-unused_crate_dependencies

<!--
Thank you for filing a bug report! 🐛 Please provide a short summary of the bug,
along with any information you feel relevant to replicating the bug.
-->

## I tried this code:

Consider a crate setup with the `clap` dependency, where `clap` is used only by the `lib` target:

`Cargo.toml`:
```toml
[package]
name = "multiple_targets"

[dependencies]
clap = { version = "3", features = ["derive"] }
```

`src/lib.rs`:
```rust
use clap::Parser;

#[derive(Parser)]
pub struct Args {}
```

This is fine when checking with this lint enabled:

```console
$ RUSTFLAGS=-Wunused-crate-dependencies cargo c --all --all-targets
```

Now, consider adding multiple targets to this crate. For the sake of demonstration, we use a `test` and `bin` target that both utilize the library crate defined above:

`src/main.rs`:
```rust
fn main() {
    let _x = multiple_targets::Args {};
}
```

`tests/test.rs`:
```rust
#[test]
fn test() {
    let _x = multiple_targets::Args {};
}
```

We run the same `check` command again:

```console
$ RUSTFLAGS=-Wunused-crate-dependencies cargo c --all --all-targets
```

## I expected to see this happen:

No `` external crate `clap` unused `` warnings show up.

## Instead, this happened:

Every target seems to be checked _individually_ against the set of defined crate dependencies, instead of identifying dependencies that are not used by all targets combined (or at the very least lib+bins, as test-only dependencies should reside under `dev-dependencies`). As such, both the test and binary targets above are accused of not using `clap`:

```rust
warning: external crate `clap` unused in `multiple_targets`: remove the dependency or add `use clap as _;`
  |
  = note: requested on the command line with `-W unused-crate-dependencies`
  = help: remove unnecessary dependency `clap`

warning: external crate `clap` unused in `test`: remove the dependency or add `use clap as _;`
  |
  = note: requested on the command line with `-W unused-crate-dependencies`
  = help: remove unnecessary dependency `clap`

warning: `multiple_targets` (bin "multiple_targets") generated 1 warning
warning: `multiple_targets` (bin "multiple_targets" test) generated 1 warning (1 duplicate)
warning: `multiple_targets` (test "test") generated 1 warning
```

For the most part, especially larger library crates, this makes it impossible to write clean test binaries without having the top half filled with `use {dep_a as _, dep_b as _, ...};`.

Note that our project currently comprises 92 crates in a single `git` repository, and we use [a single `.cargo/config.toml`](https://github.com/EmbarkStudios/rust-ecosystem/blob/main/lints.toml) in the workspace root to configure lints all at once. It is completely infeasible for us to duplicate these to every existing and up and coming crate, nor keep them in sync after the fact. As such, copy-pasting `#[warn(unused-crate-dependencies)]` across just the `lib.rs`/`main.rs` bits of our code base (where only a single target is used) is pretty much impossible.

---

_EDIT: I can understand this warning to show up for the binary (test) targets if they do not reference the library target, but it is particularly confusing when these binary targets at least transitively use the dependency through the library target._

### Meta
<!--
If you're using the stable version of the compiler, you should also check if the
bug also exists in the beta or nightly versions.
-->

`rustc --version --verbose`:
```
rustc 1.61.0-nightly (c5cf08d37 2022-03-30)
binary: rustc
commit-hash: c5cf08d37b85f953b132951e868df5b924250fdc
commit-date: 2022-03-30
host: x86_64-unknown-linux-gnu
release: 1.61.0-nightly
LLVM version: 14.0.0
```