perf(lockfiles): Drop redundant human_name clone for pnpm v7/v9 (#13649)
## What
`PnpmLockfile::human_name` returned `Some(package.key.clone())` for
v7/v9 lockfiles — an exact copy of the key that the caller has *already*
stored as the resolved identity's `key`. That's **one heap allocation
per resolved package, across every workspace's dependency closure**. On
a large monorepo it was, by a wide margin, the single largest allocation
site in package-graph construction.
It's pure waste, because for v7/v9 the key already *is* the
human-readable identity:
- `ExternalPackageIdentity::display_name()` already falls back to `key`
when `human_name` is `None`.
- The resolution fingerprint hashes only `(key, version)` — `human_name`
never enters it.
- Identity `PartialEq` / `Ord` / `dedup` all ignore `human_name`.
So returning `None` for v7/v9 is **byte-for-byte identical for every
consumer** — same display name, same fingerprint, same cache keys —
while removing both the allocation and the redundant stored string.
v5 (which strips the leading `/` to form a name genuinely distinct from
the key) and the other package managers are untouched.
## Correctness
- Display output is unchanged: every current consumer of the name goes
through `display_name()`, which yields `key` in both the old
(`Some(key)`) and new (`None`) cases.
- Cache stability is preserved: the generation fingerprint is derived
solely from `(key, version)`, so no cache keys move.
- Tests: `turborepo-lockfiles` (281), `turborepo-repository`, and
`turborepo-query` all pass unchanged; `cargo clippy` clean under
`#[deny(clippy::all)]`.
## Measured impact
Package-graph build on a real ~1,200-workspace monorepo, heap-profiled
with dhat (total allocations over the build):
| | allocations | bytes |
|---|---|---|
| before | 2,179,449 | 309.5 MB |
| after | 1,790,681 | 299.4 MB |
| **delta** | **~389k fewer (~18%)** | **~10 MB less** |
---------
Co-authored-by: Claude <noreply@anthropic.com>