BE-640: Fix cargo unused_dependencies warnings and surface them in CI#8963
BE-640: Fix cargo unused_dependencies warnings and surface them in CI#8963TimDiekmann wants to merge 1 commit into
Conversation
PR SummaryLow Risk Overview Across ~38 crates, dependency diagrams are embedded with unconditional
Reviewed by Cursor Bugbot for commit e5ffd02. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Pull request overview
This PR addresses persistent Rust cargo::unused_dependencies manifest warnings across the workspace and ensures they’re surfaced as CI failures, preventing them from silently accumulating in green builds.
Changes:
- Updates many Rust crates to use an unconditional
#![doc = simple_mermaid::mermaid!(…)]attribute sosimple-mermaidis considered “used” in non-doc builds. - Removes or rewires unused/misconfigured dependencies and features (e.g.,
reqwest/stream, optionalclap_builder, removal of unused crates). - Adds a CI gate in
lint.ymlto detect manifest-lint warnings from clippy output logs and fail the job.
Reviewed changes
Copilot reviewed 47 out of 48 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/graph/test-data/rust/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/error-stack/src/fmt/hook.rs | Anchor spin in std + hooks builds to satisfy unused-dep lint. |
| libs/@local/temporal-client/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/telemetry/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/telemetry/Cargo.toml | Make clap_builder optional and tie it to the clap feature. |
| libs/@local/status/rust/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/repo-chores/rust/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/syntax-jexpr/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/mir/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/hir/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/eval/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/diagnostics/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/diagnostics/Cargo.toml | Remove unused derive_more dependency. |
| libs/@local/hashql/core/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/core/Cargo.toml | Remove unused rpds dependency. |
| libs/@local/hashql/compiletest/src/main.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/compiletest/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/hashql/ast/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/wire-protocol/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/types/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/tower/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/system/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/server/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/net/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/codec/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/harpc/client/rust/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/validation/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/types/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/type-fetcher/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/type-fetcher/Cargo.toml | Explicitly enable reqwest’s stream feature. |
| libs/@local/graph/type-defs/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/temporal-versioning/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/store/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/postgres-store/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/migrations/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/migrations-macros/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/authorization/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/authorization/Cargo.toml | Remove unused reqwest, futures, and futures-core dependencies. |
| libs/@local/graph/api/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/graph/api/Cargo.toml | Remove unused opentelemetry_sdk dependency. |
| libs/@local/effect-dns/hickory/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/codegen/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@local/codec/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@blockprotocol/type-system/rust/src/lib.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| libs/@blockprotocol/type-system/rust/Cargo.toml | Remove unused futures dependency. |
| Cargo.lock | Update lockfile to reflect dependency removals/feature changes. |
| apps/hash-graph/src/main.rs | Make mermaid doc attribute unconditional to avoid unused-dep manifest lint. |
| .github/workflows/lint.yml | Tee clippy output for grep-based manifest-lint gating in CI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| run: | | ||
| pushd ${{ matrix.path }} | ||
| turbo run lint:clippy --filter "${{ matrix.name }}" -- --message-format=json \ |
Benchmark results
|
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 2002 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 1002 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 3314 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 1527 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 2078 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 1033 | Flame Graph |
policy_resolution_medium
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 102 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 52 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 269 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 108 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 133 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 63 | Flame Graph |
policy_resolution_none
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 2 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 2 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 8 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 3 | Flame Graph |
policy_resolution_small
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| resolve_policies_for_actor | user: empty, selectivity: high, policies: 52 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: empty, selectivity: medium, policies: 26 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: high, policies: 94 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: seeded, selectivity: medium, policies: 27 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: high, policies: 66 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: low, policies: 1 | Flame Graph | |
| resolve_policies_for_actor | user: system, selectivity: medium, policies: 29 | Flame Graph |
read_scaling_complete
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id;one_depth | 1 entities | Flame Graph | |
| entity_by_id;one_depth | 10 entities | Flame Graph | |
| entity_by_id;one_depth | 25 entities | Flame Graph | |
| entity_by_id;one_depth | 5 entities | Flame Graph | |
| entity_by_id;one_depth | 50 entities | Flame Graph | |
| entity_by_id;two_depth | 1 entities | Flame Graph | |
| entity_by_id;two_depth | 10 entities | Flame Graph | |
| entity_by_id;two_depth | 25 entities | Flame Graph | |
| entity_by_id;two_depth | 5 entities | Flame Graph | |
| entity_by_id;two_depth | 50 entities | Flame Graph | |
| entity_by_id;zero_depth | 1 entities | Flame Graph | |
| entity_by_id;zero_depth | 10 entities | Flame Graph | |
| entity_by_id;zero_depth | 25 entities | Flame Graph | |
| entity_by_id;zero_depth | 5 entities | Flame Graph | |
| entity_by_id;zero_depth | 50 entities | Flame Graph |
read_scaling_linkless
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id | 1 entities | Flame Graph | |
| entity_by_id | 10 entities | Flame Graph | |
| entity_by_id | 100 entities | Flame Graph | |
| entity_by_id | 1000 entities | Flame Graph | |
| entity_by_id | 10000 entities | Flame Graph |
representative_read_entity
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/block/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/book/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/building/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/organization/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/page/v/2
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/person/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/playlist/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/song/v/1
|
Flame Graph | |
| entity_by_id | entity type ID: https://blockprotocol.org/@alice/types/entity-type/uk-address/v/1
|
Flame Graph |
representative_read_entity_type
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| get_entity_type_by_id | Account ID: bf5a9ef5-dc3b-43cf-a291-6210c0321eba
|
Flame Graph |
representative_read_multiple_entities
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| entity_by_property | traversal_paths=0 | 0 | |
| entity_by_property | traversal_paths=255 | 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true | |
| entity_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=0 | 0 | |
| link_by_source_by_property | traversal_paths=255 | 1,resolve_depths=inherit:1;values:255;properties:255;links:127;link_dests:126;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:0;link_dests:0;type:false | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:0;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:0;properties:2;links:1;link_dests:0;type:true | |
| link_by_source_by_property | traversal_paths=2 | 1,resolve_depths=inherit:0;values:2;properties:2;links:1;link_dests:0;type:true |
scenarios
| Function | Value | Mean | Flame graphs |
|---|---|---|---|
| full_test | query-limited | Flame Graph | |
| full_test | query-unlimited | Flame Graph | |
| linked_queries | query-limited | Flame Graph | |
| linked_queries | query-unlimited | Flame Graph |
🌟 What is the purpose of this PR?
Cargo's
unused_dependencieslint (active through the repo'scargo-lintsopt-in since at leastnightly-2026-06-08) has been reporting unused dependencies for weeks, but nobody saw/complained about it: the warnings are cargo manifest diagnostics emitted as plain text, not compiler JSON messages, so they bypass the SARIF gate in CI and only ever existed in unread logs of green jobs. Locally they are equally easy to miss because cargo only reports them for primary packages of an invocation.This PR fixes every current finding across the workspace and adds a CI gate so new ones fail the lint job.
🔗 Related links
cargo cleanbuild)🚫 Blocked by
Nothing.
🔍 What does this change?
#![cfg_attr(doc, doc = simple_mermaid::mermaid!(…))]with an unconditional#![doc = …]. The dependency is compiled in every build anyway and doc attributes are inert outside rustdoc, but thecfg_attrvariant made every non-doc build considersimple-mermaidunused.reqwest,futures,futures-core(hash-graph-authorization),rpds(hashql-core),derive_more(hashql-diagnostics),opentelemetry_sdk(hash-graph-api),futures(type-system).reqwest/streamfeature itself. It usesResponse::bytes_streambut previously only compiled because hash-graph-authorization's (unused) reqwest dependency enabled the feature via unification.spinwith ause spin as _;gated onall(feature = "std", feature = "hooks")— it is genuinely used, but only on no-std paths, sostd+hooksbuilds flagged it. A per-crate[lints.cargo]override is not possible next tolints.workspace = true.clap_builderoptional and wire it into theclapfeature; it is only referenced by theclap::Argsderives behind that feature.lint.yml):teethe clippy stream intoclippy-output.logand fail the step when it containswarning: unused dependencyor(manifest) generatedlines. This catches all cargo manifest lints with zero additional build time. A workspace-widedenylevel was deliberately rejected because it would make local builds fail mid-refactor.Pre-Merge Checklist 🚀
🚢 Has this modified a publishable library?
This PR:
📜 Does this require a change to the docs?
The changes in this PR:
🕸️ Does this require a change to the Turbo Graph?
The changes in this PR:
--all-features, which by construction cannot detect dependencies that are unused only in some feature combinations (theclap_builderclass). Those are still caught by thecargo hack --feature-powersetrun outside of pull requests.clippy-sarifhas no JSON events to convert.🐾 Next steps
--message-format=json(the lint system is still unstable), the grep gate can be folded into the SARIF pipeline.🛡 What tests cover this?
cargo check --workspace --all-featuresis warning-free (run to fixpoint locally).cargo check -p error-stack --all-featuresand--no-default-features --features hooksboth clean.❓ How to test this?
cargo clean && cargo check --workspace --all-features— nounused dependencywarnings appear.Cargo.tomland push — the "Run clippy" step for that package fails with the offending lines in the log.📹 Demo