feat(workspace): enable and enforce unreachable_pub lint#493
Conversation
Add unreachable_pub = "warn" to [workspace.lints.rust]. Member crates inherit it via [lints] workspace = true. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve all `unreachable_pub` warnings surfaced by enabling the lint, using the least-privilege fix for each offender: - Hand-written items (fns, methods, structs, enums, traits, type aliases, pub use re-exports) flagged across ~20 crates: change `pub` -> `pub(crate)`. Applied mechanically via `cargo clippy --fix`. - cachet_tier::CacheTier: the trait is re-exported at the crate root via `pub use tier::CacheTier`, but the `#[dynosaur::dynosaur]` attribute macro causes the lint to misfire on the generated definition. Keep it `pub` and suppress with a module-level `#![expect(unreachable_pub)]` (item-level `#[expect]` is unreliable across the macro expansion). - fundle bundle test component structs (Instance/Device/Vulkan): must stay `pub` because `#[fundle::bundle]` generates a public interface over them (E0446 otherwise); annotate each with `#[expect(...)]`. No struct fields were touched (`unreachable_pub` does not flag fields). Visibility-only changes; no behavioral changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #493 +/- ##
=====================================
Coverage 99.9% 99.9%
=====================================
Files 336 336
Lines 24829 24829
=====================================
Hits 24818 24818
Misses 11 11 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The cfg(not(metrics/logs/test)) fallback ew was left pub while its twin and the enclosing EngineTelemetry<T> struct are pub(crate). Under --all-features this branch is compiled out, so the workspace --all-features clippy never saw it; CI's cargo hack build --each-feature builds seatbelt with metrics/logs off (e.g. --features breaker) where the branch compiles and unreachable_pub fires. This also broke the external-type-exposure check (seatbelt_http builds seatbelt with those features off). Narrowing to pub(crate) matches the struct's visibility; no public API change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR enables the unreachable_pub rustc lint across the workspace (configured as warn, and therefore enforced under CI’s -D warnings) and then resolves all offenders by tightening visibility (primarily pub → pub(crate)) or adding narrowly-scoped #[expect(unreachable_pub, reason = ...)] suppressions where macro-generated public APIs require it.
Changes:
- Add
unreachable_pub = "warn"to the root workspace Rust lints. - Reduce visibility of internal-only items across many crates to
pub(crate)to satisfyunreachable_pub. - Add targeted
#[expect(unreachable_pub, reason = ...)]suppressions for macro-generated public interfaces (e.g.,dynosaur,#[fundle::bundle]).
Reviewed changes
Copilot reviewed 83 out of 83 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| Cargo.toml | Enables unreachable_pub at the workspace lint level. |
| crates/tick/src/timers.rs | Tightens visibility of internal timer APIs to pub(crate). |
| crates/tick/src/state.rs | Tightens visibility of internal clock/timer state constructors/helpers. |
| crates/tick/examples/clock.rs | Makes example-only API crate-private. |
| crates/thread_aware/src/closure/erased.rs | Makes erased-closure helper crate-private. |
| crates/thread_aware/src/cell/mod.rs | Removes unreachable public re-export by making it crate-private. |
| crates/thread_aware/src/cell/factory.rs | Makes internal factory type alias crate-private. |
| crates/thread_aware_macros_impl/src/struct_gen.rs | Makes proc-macro helper function crate-private. |
| crates/thread_aware_macros_impl/src/enum_gen.rs | Makes proc-macro helper function crate-private. |
| crates/templated_uri_macros_impl/src/template_parser.rs | Makes parser internals crate-private. |
| crates/templated_uri_macros_impl/src/struct_template.rs | Makes derive/template internals crate-private. |
| crates/templated_uri_macros_impl/src/error.rs | Makes macro parse error type crate-private. |
| crates/templated_uri_macros_impl/src/enum_template.rs | Makes enum-template generator crate-private. |
| crates/seatbelt/src/utils/telemetry_helper.rs | Tightens helper visibility to crate-private. |
| crates/seatbelt/src/utils/mod.rs | Tightens EnableIf constructors/call to crate-private. |
| crates/seatbelt/src/testing.rs | Tightens test-support helpers to crate-private. |
| crates/seatbelt/src/rnd.rs | Tightens test-only RNG constructors and RNG method visibility. |
| crates/seatbelt/src/retry/backoff.rs | Tightens internal delay iterator accessor visibility. |
| crates/seatbelt/src/breaker/layer.rs | Makes a test function crate-private to avoid unreachable public test items. |
| crates/seatbelt/src/breaker/health.rs | Tightens health/metrics internals to crate-private. |
| crates/seatbelt/src/breaker/execution_result.rs | Tightens helper methods to crate-private under cfg-gated telemetry. |
| crates/seatbelt/src/breaker/engine/probing/single_probe.rs | Tightens probing helpers to crate-private. |
| crates/seatbelt/src/breaker/engine/probing/probes.rs | Tightens probing state methods to crate-private. |
| crates/seatbelt/src/breaker/engine/probing/options.rs | Tightens probing option constructors/accessors to crate-private. |
| crates/seatbelt/src/breaker/engine/probing/mod.rs | Tightens probe constructor visibility. |
| crates/seatbelt/src/breaker/engine/probing/health_probe.rs | Tightens health probe constructor visibility. |
| crates/seatbelt/src/breaker/engine/mod.rs | Makes internal engine alias and helper method crate-private. |
| crates/seatbelt/src/breaker/engine/engines.rs | Tightens engine factory/getter visibility. |
| crates/seatbelt/src/breaker/engine/engine_telemetry.rs | Tightens engine telemetry constructor visibility. |
| crates/seatbelt/src/breaker/engine/engine_fake.rs | Tightens fake engine constructor visibility. |
| crates/seatbelt/src/breaker/engine/engine_core.rs | Tightens engine core/stat helpers visibility. |
| crates/ohno/tests/debug_implementation_comparison.rs | Tightens test-local reference types to crate-private. |
| crates/ohno/src/source.rs | Makes internal enum crate-private. |
| crates/ohno/src/enrichable.rs | Tightens test-only type visibility. |
| crates/ohno/src/core.rs | Makes internal boxed core representation crate-private. |
| crates/ohno_macros/src/utils.rs | Tightens macro helper function visibility. |
| crates/ohno_macros/src/error_type_attr.rs | Tightens proc-macro entrypoint visibility (internal wiring). |
| crates/ohno_macros/src/enrich_err/mod.rs | Tightens proc-macro entrypoint + helper visibility. |
| crates/ohno_macros/src/derive_error/types.rs | Tightens derive internals to crate-private. |
| crates/ohno_macros/src/derive_error/mod.rs | Stops publicly re-exporting derive internals; makes module items crate-private. |
| crates/ohno_macros/src/derive_error/from_impls.rs | Tightens derive helper visibility. |
| crates/ohno_macros/src/derive_error/field_detection.rs | Tightens derive helper visibility. |
| crates/ohno_macros/src/derive_error/display.rs | Tightens derive helper visibility. |
| crates/ohno_macros/src/derive_error/constructors.rs | Tightens derive helper visibility. |
| crates/ohno_macros/src/derive_error/attributes.rs | Tightens derive helper visibility. |
| crates/multitude/tests/coverage_gaps.rs | Tightens test-only allocator helper visibility. |
| crates/multitude/tests/common/mod.rs | Tightens shared test helpers/types visibility. |
| crates/layered/src/testing.rs | Tightens testing helper constructor visibility. |
| crates/layered/src/intercept.rs | Makes test function crate-private to avoid unreachable public test items. |
| crates/http_extensions/src/json.rs | Makes test functions crate-private to avoid unreachable public test items. |
| crates/http_extensions/src/http_utils.rs | Tightens internal helper constructors to crate-private. |
| crates/fundle/tests/bundle_getters.rs | Adds #[expect(unreachable_pub)] on bundle component types required to remain pub. |
| crates/fundle/tests/bundle_all_features.rs | Adds #[expect(unreachable_pub)] on bundle component types required to remain pub. |
| crates/fetch/src/telemetry.rs | Tightens internal telemetry constructor visibility. |
| crates/fetch/src/pipeline/custom.rs | Tightens internal pipeline factory API visibility. |
| crates/fetch/src/pipeline/builder.rs | Tightens test-only helpers to crate-private. |
| crates/fetch/src/handlers/transport.rs | Tightens internal handler constructor visibility. |
| crates/fetch/src/handlers/dispatch.rs | Tightens internal dispatch constructors visibility. |
| crates/fetch/src/custom.rs | Tightens internal transport helper methods visibility. |
| crates/fetch/examples/util/utils.rs | Makes example tracing init crate-private. |
| crates/fetch/examples/http_client_api_with_templated_uri.rs | Makes example client/types crate-private. |
| crates/fetch_tls/src/testing.rs | Tightens test-only TLS helpers to crate-private. |
| crates/fetch_tls/src/rustls.rs | Tightens internal verifier factory helpers to crate-private. |
| crates/data_privacy/src/redactors/mod.rs | Tightens internal helper function visibility. |
| crates/data_privacy/src/redaction_engine_inner.rs | Tightens internal engine methods visibility. |
| crates/data_privacy/examples/employees/logging.rs | Makes example helpers crate-private. |
| crates/data_privacy/examples/employees/employee.rs | Makes example model types crate-private. |
| crates/data_privacy_macros_impl/src/taxonomy.rs | Tightens proc-macro helper visibility. |
| crates/data_privacy_macros_impl/src/classified.rs | Tightens proc-macro helper visibility. |
| crates/cachet/src/wrapper.rs | Makes internal wrapper type crate-private (remains usable via builder composition). |
| crates/cachet/src/transform/testing.rs | Tightens test-support codec visibility. |
| crates/cachet/src/serialize/codec.rs | Tightens internal postcard codec types/ctors visibility. |
| crates/cachet/src/refresh.rs | Tightens internal refresh helper visibility. |
| crates/cachet/src/fallback.rs | Makes internal fallback cache wrapper crate-private. |
| crates/cachet_tier/src/tier.rs | Adds module-level #![expect(unreachable_pub)] due to dynosaur macro interaction. |
| crates/bytesbuf/src/vec.rs | Tightens internal helper constructor visibility. |
| crates/bytesbuf/src/span.rs | Tightens internal accessor visibility. |
| crates/bytesbuf/src/mem/testing/std_alloc_block.rs | Tightens test-only allocator helper visibility. |
| crates/bytesbuf/src/bytes_compat/from_bytes.rs | Tightens internal helper constructor visibility. |
| crates/bytesbuf/examples/bb_optimal_path.rs | Makes example-only APIs crate-private. |
| crates/bytesbuf/examples/bb_has_memory_optimizing.rs | Makes example-only APIs crate-private. |
| crates/bytesbuf/examples/bb_has_memory_global.rs | Makes example-only APIs crate-private. |
| crates/bytesbuf/examples/bb_has_memory_forwarding.rs | Makes example-only APIs crate-private. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- cachet_tier/tier.rs: replace the crate-wide module-level #![expect] with an item-level attribute on the CacheTier trait. item-level #[expect] is unfulfilled here (the dynosaur attribute macro does not attribute the diagnostic to the trait node), so use a scoped #[allow(clippy::allow_attributes, unreachable_pub, ...)] -- matching the existing pattern in thread_aware/src/registry.rs. - fundle tests: replace the three per-struct #[expect] attributes with a single module-level #![expect(unreachable_pub, ...)] to reduce test boilerplate, as suggested. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
What
Enables and enforces the
unreachable_pubrustc lint across the workspace, then fixes every offender.unreachable_pub = "warn"to[workspace.lints.rust]in the rootCargo.toml(alphabetically placed betweentrivial_numeric_castsandunsafe_op_in_unsafe_fn). Member crates already inherit workspace lints via[lints] workspace = true.cargo clippy --workspace --all-targets --all-features --locked -- -D warnings(the way CI runs clippy).How offenders were resolved (least-privilege)
pub usere-exports) across ~20 crates:pub->pub(crate). Applied mechanically withcargo clippy --fix; the few cases clippy emitted aspub(super)were normalized topub(crate)for uniformity.cachet_tier::CacheTier: the trait is genuinely public (re-exported at the crate root viapub use tier::CacheTier), but the#[dynosaur::dynosaur]attribute macro makesunreachable_pubmisfire on the generated definition. Keptpuband suppressed with an item-scoped#[allow(clippy::allow_attributes, unreachable_pub, ...)]on the trait (an item-level#[expect]is reported unfulfilled across the macro expansion, and theclippy::allow_attributesself-allow matches the existing pattern inthread_aware/src/registry.rs).Instance/Device/Vulkan): must staypubbecause#[fundle::bundle]generates a public interface over them (downgrading topub(crate)yieldsE0446). Suppressed with a single module-level#![expect(unreachable_pub, ...)]per test file.No
pubstruct fields were touched (unreachable_pubdoes not flag fields). There are noinclude!-generated sources or cfg-gated platform-placeholder modules among the offenders, so those suppression categories did not apply. All changes are visibility-only with no behavioral changes.Verification
cargo clippy --workspace --all-targets --all-features --locked -- -D warnings-- clean (exit 0).cargo build --workspace --all-features --all-targets --locked-- clean.cargo test --workspace --all-features --locked-- all pass, 0 failures.cargo doc --no-deps --workspace --all-featureswithRUSTDOCFLAGS="-D warnings"-- clean.rustfmt --check(stable,max_width=140) on all changed files -- clean.Note:
just format-checkand the--cfg docsrsdocs build use the pinned nightly toolchain (nightly-2026-05-30), which is validated in CI. The changes are import-free and do not touch doc code blocks, so the stable rustfmt check is a faithful proxy for the formatting gate.