From 8fed5c181327d5bd7cd295d4e4be856bdb5b4dd6 Mon Sep 17 00:00:00 2001 From: atlas Date: Fri, 14 Aug 2026 02:19:45 +0200 Subject: [PATCH] refactor(#3245): move the rustdoc lints into the workspace lint table mara asked whether these can live in Cargo.toml. They can, and they should: [workspace.lints.rustdoc] sits alongside the existing clippy table, every crate already opts in via `[lints] workspace = true`, and the toolchain is well past the 1.74 that introduced lint tables. The reason it is better than RUSTDOCFLAGS on the check: a plain local `cargo doc` now fails exactly the way CI does. Setting the lints only in the nix derivation would have made CI the one place the gate exists, which is the same "you meet it too late" problem the gate was written to solve. The check keeps --workspace --no-deps --document-private-items and drops the RUSTDOCFLAGS block entirely. Verified by mutation rather than assumption, with no RUSTDOCFLAGS set anywhere: clean tree exits 0; reintroducing one broken link makes `cargo doc -p hive-jobq` exit 101 with `error: public documentation for Outcome links to private item Scheduler::complete`. An error rather than a warning is the proof the deny came from the lint table. --- Cargo.toml | 17 +++++++++++++++++ nix/checks.nix | 18 ++++++------------ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0ba429a1..184b75b3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,23 @@ missing_panics_doc = "allow" module_name_repetitions = "allow" must_use_candidate = "allow" +[workspace.lints.rustdoc] +# Doc-link rot has no other discoverer: clippy does not read intra-doc +# links, `cargo test` does not, and nothing else builds docs. A `[`Foo`]` +# pointing at a renamed, moved or deleted item renders as plain text and +# misleads the next reader — worse than no link, since it names something +# and so sends them looking. +# +# Here rather than in `RUSTDOCFLAGS` on the CI check, so a plain local +# `cargo doc` fails the same way CI does. A gate you only meet in CI is a +# gate you meet too late. +broken_intra_doc_links = "deny" +private_intra_doc_links = "deny" +invalid_html_tags = "deny" +redundant_explicit_links = "deny" +bare_urls = "deny" +unescaped_backticks = "deny" + [workspace.dependencies] anyhow = "1" libc = "0.2" diff --git a/nix/checks.nix b/nix/checks.nix index 56a1a935..7181e8f7 100644 --- a/nix/checks.nix +++ b/nix/checks.nix @@ -97,18 +97,12 @@ in pname = "hyperhive-workspace"; version = "0.1.0"; cargoDocExtraArgs = "--workspace --no-deps --document-private-items"; - # Every rustdoc lint that catches a *wrong* doc, denied. Kept as an - # explicit list rather than a blanket `-D warnings` so that adding a - # new rustdoc lint upstream can't silently red the build on a class - # nobody has triaged yet. - RUSTDOCFLAGS = builtins.concatStringsSep " " [ - "-D rustdoc::broken_intra_doc_links" - "-D rustdoc::private_intra_doc_links" - "-D rustdoc::invalid_html_tags" - "-D rustdoc::redundant_explicit_links" - "-D rustdoc::bare_urls" - "-D rustdoc::unescaped_backticks" - ]; + # The lints themselves are NOT set here — they live in + # `[workspace.lints.rustdoc]` in the root Cargo.toml, alongside the + # clippy table, and every crate inherits them via `[lints] workspace + # = true`. That way a plain local `cargo doc` fails exactly the way + # this check does; setting them as `RUSTDOCFLAGS` here would make CI + # the only place the gate exists. }; # Nix options docs evaluation. Cheap: pulls in `nixosOptionsDoc` +