Analyze and fix across a configured list of compilation targets
[!NOTE]
This PR — the code, tests, docs, and this description — was entirely generated by Claude Code, at the direction of @Jarred-Sumner for use in Bun.
Summary
Add a targets configuration list so a single cargo hawk check compiles the workspace for several target triples and unions the reachability evidence across all of them before producing diagnostics:
targets = ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin", "x86_64-pc-windows-msvc"]
Hawk already unions evidence across [[feature-profile]] entries; this extends that same dimension to compilation targets. Every production binary and workspace non-production target is compiled once per (feature profile, target), so a declaration required on any configured platform is preserved. With no targets configured, behavior is unchanged (the host target, or --target). --target on the command line is rejected when a targets list is configured.
Motivation
We hit this analyzing Bun's Rust workspace (~200 crates, 11 shipped triples). A single-target run reports Windows-only FFI and Darwin-only code as dead, so to get a set that is safe to delete we currently run Hawk once per triple and intersect the findings by hand — and --fix is unusable because it would restrict surface another platform still needs. With this change, a two-target run over the workspace produces the platform-correct set directly (verified: no cfg(windows)-only declarations reported when analyzing from a Linux host).
--fix with multiple configurations
To make the union actionable, --fix now computes one fix plan from the combined evidence and applies it under every configured feature profile and target before re-analyzing, so a declaration compiled in only one configuration is edited by that configuration's pass. This lifts the existing guard that rejected --fix with multiple feature profiles. I'm happy to split that behavior into a separate PR if you'd prefer to review it independently.
Tests
- New
multi_targetsfixture: a library withcfg(unix)-only andcfg(windows)-only public APIs and helpers, an app calling both under matching cfgs, and a genuinely deadpub fn. Tests assert the union keeps the platform APIs, still reports the truly dead item, and that--fix --allow-no-vcsrestricts only what is unused on every target. Also covers the--targetvstargetsconflict. - New
feature_profile_fixesfixture covering--fixacross feature profiles. - Config parsing tests for the
targetslist (defaults, duplicates, empty entries). rust-toolchain.tomlgainsx86_64-pc-windows-msvcsorustup showin CI installs the second target's std for the fixture.
cargo test --workspace --all-features --locked, cargo fmt, and cargo clippy --workspace --all-targets --all-features -- -D warnings are clean locally.