Module check_lints
Expand description
cargo dev check-lints — the one crate that cannot inherit the workspace
lints still enforces every one of them.
§Why this command exists
Ground rule 2 forbids unsafe workspace-wide, and atune_py is the single
documented relaxation: its PyO3 bridge needs the hand-written lifetime and
pointer operations enumerated in OPERATIONS, and pyo3’s own proc-macros
expand to unsafe that a crate-level forbid
rejects. [lints] workspace = true would re-impose forbid and cannot be
relaxed afterwards, so atune_py cannot inherit the table at all. It
therefore copies it, with the single change unsafe_code = "forbid" → "deny".
A copy holds only until somebody edits the original. Add a lint to
[workspace.lints] and nine crates gain it while the tenth silently does
not — and the tenth is the one crate in the workspace that writes unsafe.
That is exactly the failure this repository gates everywhere else: a
generated page that drifts from its source is a red build (generate-all --mode check), and a hand-copied lint table is the same shape of claim with
none of the same protection.
§What is checked
For each of [lints.rust] and [lints.clippy], the mirror must carry
exactly the workspace’s keys, with the same values, except for the keys
named in RELAXATIONS — each of which must be present, must differ, and
must differ in the recorded direction. So all four ways the mirror can rot
are failures:
- a workspace lint the mirror never gained,
- a mirror lint the workspace does not have (a private tightening is fine to
want, but it belongs in the crate’s own
#![…]attributes rather than in a table that claims to be a mirror), - a level or priority that has drifted apart,
- a relaxation that was quietly widened, narrowed, or removed.
Values are compared by their rendered TOML, so "warn" and
{ level = "warn", priority = -1 } are correctly different: a priority is
load-bearing for a lint group and copying one without the other is precisely
the drift worth catching.
§The second half: what the relaxation actually bought
Mirroring the table correctly still leaves the relaxation itself unbounded,
because deny is not forbid. forbid cannot be overridden from inside the
crate; deny can, by an #[allow(unsafe_code)] on any item — which is
exactly how atune_py’s existing operations are written. So the manifest
says “this crate may contain unsafe” and nothing at all says how much.
The design’s claim is much narrower than that: a small, enumerated set of
operations, each with an argument attached to it.
OPERATIONS is that enumeration, and the second half of this command
holds the tree to it. Every hand-written unsafe in crates/atune_py/src is
found by parsing the sources — unsafe blocks, unsafe impls, unsafe fns,
unsafe traits and unsafe extern blocks — and its stable AST identity must
match the record. The four admitted operations also need their local
// SAFETY: rationale; neither check depends on line numbers. A new
unsafe block is then a red gate that names the changed operation, not a
line in a diff nobody was looking at.
An inner #![allow(unsafe_code)] is rejected outright wherever it appears.
Its whole effect is to turn the deny off for a whole module or crate
rather than for one reviewed operation, which is the one shape of override
that has no legitimate use here.
§What it does not check
That the relaxation is sound — that stays a matter for review and for the
comments in crates/atune_py/Cargo.toml and ownership.rs. This command
checks that each local rationale is the one recorded for its AST identity;
it does not attempt to prove the argument. The mirror is likewise the
workspace table plus the relaxations written down, so a new relaxation is a
deliberate edit to RELAXATIONS and shows up in a diff as one.
Nor does it see unsafe produced by a macro expansion: the source parse
stops at the macro invocation, so pyo3::append_to_inittab!’s own unsafe
block is invisible here — correctly, since the point of the inventory is the
unsafe this repository writes and has to justify, not the unsafe a
dependency’s macro expands to. The consequence is that hiding an operation
inside a macro_rules! would evade the count; that is a reviewable edit of a
different and more visible kind.
Structs§
- Counts 🔒
- The hand-written operations found in the source tree, plus the blanket overrides and local safety comments.
- Observed
Operation 🔒 - One operation observed in the parsed source tree.
- Operation 🔒
- One recorded, hand-written
unsafeoperation. - Relaxation 🔒
- One recorded, deliberate difference between the workspace table and the mirror.
- Scan 🔒
- The syn walk that fills a
Counts.
Enums§
- Kind 🔒
- The kinds of hand-written
unsafethe inventory distinguishes.
Constants§
- MIRROR_
CRATE 🔒 - The crate whose lint table is a hand-written mirror.
- MIRROR_
SRC 🔒 - The source tree the
OPERATIONSinventory covers. - OPERATIONS 🔒
- Every hand-written
unsafeoperation the relaxation is there to permit. - RELAXATIONS 🔒
- The lints the mirror is allowed to state differently, and why.
- TABLES 🔒
- The two lint tables, in the order they are reported.
Functions§
- blanket_
failures 🔒 - block_
identity 🔒 - Stable identity for the body of an unsafe block. The expression tree keeps the operation’s semantic shape while discarding formatting and spans.
- check_
relaxation 🔒 - The failures for a recorded relaxation that is no longer what was recorded.
- compare 🔒
- Compares one table, returning a failure per drifted lint.
- compare_
operation_ 🔒counts - compare_
operation_ 🔒identities - compare_
operations 🔒 - Compares the tree against
OPERATIONS, returning a failure per surprise. - compare_
safety_ 🔒comments - display 🔒
- Renders a path relative to the repository root where possible.
- diverged 🔒
- The failure for two tables that state the same lint differently.
- document 🔒
- Reads and parses a manifest.
- expression_
identity 🔒 - generic_
argument_ 🔒identity - impl_
identity 🔒 - Stable identity for an
unsafe impl, retaining both sides of the promise. - inventory 🔒
- Finds the hand-written
unsafeoperations underdir, and reports an inner#![allow(unsafe_code)]as an operation of its own so it cannot pass by being merely uncounted. Each AST operation is paired, in source order, with one local// SAFETY:comment block. - lints 🔒
- Extracts one lint table as
lint -> rendered value. - missing 🔒
- The failure for a workspace lint the mirror never gained.
- missing_
relaxation 🔒 - The failure for a relaxed lint that the mirror does not state at all.
- names_
unsafe_ 🔒code - Whether
unsafe_codeappears anywhere in a token stream. - normalize_
text 🔒 - Whitespace is presentation, not part of a safety rationale’s identity.
- operation_
drift 🔒 - The failure for a changed or missing operation identity or rationale.
- path_
arguments_ 🔒identity - path_
identity 🔒 - Stable identity for a path, including the type/lifetime arguments that are meaningful to the four recorded operations.
- recorded_
operations 🔒 - relaxes_
unsafe_ 🔒code - Whether an attribute loosens
unsafe_code. - run
- Runs the check.
- safety_
comments 🔒 - Collects contiguous
// SAFETY:comment blocks in source order. - sources 🔒
- Every
.rsfile underdir, in a stable order. - statement_
identity 🔒 - type_
identity 🔒 - unexpected_
operation 🔒 - The failure for an operation in a file/kind group with no recorded twin.
- unsafe_
drift 🔒 - The failure for a file whose count of one
unsafekind is not the recorded one, quoting the record so a reviewer sees what was supposed to be there. - wraps_
a_ 🔒relaxation - Whether a token stream contains
allow(… unsafe_code …)or theexpectspelling of it, at any depth.