Analyze and fix across a configured list of compilation targets

JA
3mo ago
+579-219

[!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_targets fixture: a library with cfg(unix)-only and cfg(windows)-only public APIs and helpers, an app calling both under matching cfgs, and a genuinely dead pub fn. Tests assert the union keeps the platform APIs, still reports the truly dead item, and that --fix --allow-no-vcs restricts only what is unused on every target. Also covers the --target vs targets conflict.
  • New feature_profile_fixes fixture covering --fix across feature profiles.
  • Config parsing tests for the targets list (defaults, duplicates, empty entries).
  • rust-toolchain.toml gains x86_64-pc-windows-msvc so rustup show in 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.