Skip to main content

Module check_lints

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.
ObservedOperation 🔒
One operation observed in the parsed source tree.
Operation 🔒
One recorded, hand-written unsafe operation.
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 unsafe the inventory distinguishes.

Constants§

MIRROR_CRATE 🔒
The crate whose lint table is a hand-written mirror.
MIRROR_SRC 🔒
The source tree the OPERATIONS inventory covers.
OPERATIONS 🔒
Every hand-written unsafe operation 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 unsafe operations under dir, 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_code appears 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 .rs file under dir, 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 unsafe kind 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 the expect spelling of it, at any depth.