rust@v1
Hygiene checks for Rust projects. Adopt it with:
extends: - alint://bundled/rust@v1 This ruleset is gated with when: facts.has_rust (true if any
Cargo.toml exists anywhere in the tree) plus a per-rule
scope_filter: { has_ancestor: Cargo.toml } on per-file content
rules so they only apply to files inside a Rust package — useful
in polyglot monorepos where Rust packages sit alongside
Node / Python / Go subdirectories. Rules that don't apply stay
quiet. (has_rust is declared below; override with your own
facts: block if you need a different heuristic.)
What it checks
Section titled "What it checks"10 rules. Each links to its section below, which explains the check and shows its definition.
| Rule | Reports |
|---|---|
rust-cargo-toml-existserror | Rust project: Cargo.toml at the repo root is required. |
rust-cargo-lock-existswarning | Committing Cargo.lock ensures reproducible builds for binary crates. |
rust-toolchain-pinnedinfo | Pinning a toolchain (rust-toolchain.toml) makes local and CI builds reproducible. |
rust-no-tracked-targeterror | target/ is Cargo's build dir and must never be committed. |
rust-sources-snake-caseerror | Rust module filenames must be snake_case. |
rust-sources-final-newlinewarning | File must end with a single \n. |
rust-sources-no-trailing-whitespaceinfo | No line may end with space or tab. |
rust-sources-no-bidierror | Trojan Source (CVE-2021-42574): bidi override chars in Rust sources are rejected. |
rust-sources-no-zero-widtherror | Zero-width characters in Rust sources are rejected (review hazard). |
rust-no-merge-markers-in-manifestserror | Flag <<<<<<<, =======, >>>>>>>, ||||||| markers at the start of a line, almost always left over... |
All 10 rules run only when facts.has_rust holds, so the ruleset stays quiet in repositories it doesn't apply to.
rust-cargo-toml-exists
Section titled "rust-cargo-toml-exists"- kind:
file_exists - level:
error - when:
facts.has_rust
Rust project: Cargo.toml at the repo root is required.
- id: rust-cargo-toml-exists when: facts.has_rust kind: file_exists paths: Cargo.toml root_only: true level: error message: "Rust project: Cargo.toml at the repo root is required."rust-cargo-lock-exists
Section titled "rust-cargo-lock-exists"- kind:
file_exists - level:
warning - when:
facts.has_rust - policy: https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Committing Cargo.lock ensures reproducible builds for binary crates. Library-only workspaces may legitimately opt out; set this rule's
level: offin that case.
- id: rust-cargo-lock-exists when: facts.has_rust kind: file_exists paths: Cargo.lock root_only: true level: warning message: >- Committing Cargo.lock ensures reproducible builds for binary crates. Library-only workspaces may legitimately opt out; set this rule's `level: off` in that case. policy_url: "https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html" rust-toolchain-pinned
Section titled "rust-toolchain-pinned"- kind:
file_exists - level:
info - when:
facts.has_rust
Pinning a toolchain (rust-toolchain.toml) makes local and CI builds reproducible.
- id: rust-toolchain-pinned when: facts.has_rust kind: file_exists paths: ["rust-toolchain.toml", "rust-toolchain"] root_only: true level: info message: "Pinning a toolchain (rust-toolchain.toml) makes local and CI builds reproducible."rust-no-tracked-target
Section titled "rust-no-tracked-target"- kind:
dir_absent - level:
error - when:
facts.has_rust
target/is Cargo's build dir and must never be committed.
- id: rust-no-tracked-target when: facts.has_rust kind: dir_absent paths: "**/target" level: error message: "`target/` is Cargo's build dir and must never be committed." rust-sources-snake-case
Section titled "rust-sources-snake-case"Changed in v0.9.18: default-exclude subtrees with deliberately non-snake-case filenames. Three categories surface in rust-lang/rust:
src/doc/** — doc examples + reference snippets use English-style hyphenation (`rustc-driver-example.rs`, `rust-by-example/...`).src/tools/miri/tests/** — Miri test fixtures use CamelCase / intentional naming for litmus tests and concurrency-spec semantics (`abi_mismatch_repr_C.rs`, `libc_pthread_mutex_NULL_reentrant.rs`).src/tools/clippy/tests/ui/** — clippy UI test fixtures use curly braces, hyphens, and other non-snake-case markers as part of the test grammar.**/*.miri.rs — `.miri.rs` dot-suffix is a Miri-only override file pattern; the dot in the basename trips snake-case.Without these excludes, rust-lang/rust alone surfaced 1,091 false positives — the largest single bundled-rule FP class in the case-study corpus. The excludes are unique to rust-lang/rust + similar compiler/test-fixture projects; they're a no-op for most repos.
- kind:
filename_case - level:
error - when:
facts.has_rust - fix:
file_rename(applied byalint fix)
Rust module filenames must be snake_case.
- id: rust-sources-snake-case when: facts.has_rust kind: filename_case paths: include: ["**/src/**/*.rs" ] exclude: - "src/doc/**" - "src/tools/miri/tests/**" - "src/tools/clippy/tests/ui/**" - "src/tools/rustfmt/tests/**" - "tests/rustdoc-gui/**" - "**/*.miri.rs" case: snake level: error message: "Rust module filenames must be snake_case." fix: file_rename: {}rust-sources-final-newline
Section titled "rust-sources-final-newline"- kind:
final_newline - level:
warning - when:
facts.has_rust - fix:
file_append_final_newline(applied byalint fix)
- id: rust-sources-final-newline when: facts.has_rust kind: final_newline paths: "**/*.rs" scope_filter: has_ancestor: Cargo.toml level: warning fix: file_append_final_newline: {}rust-sources-no-trailing-whitespace
Section titled "rust-sources-no-trailing-whitespace"- kind:
no_trailing_whitespace - level:
info - when:
facts.has_rust - fix:
file_trim_trailing_whitespace(applied byalint fix)
- id: rust-sources-no-trailing-whitespace when: facts.has_rust kind: no_trailing_whitespace paths: "**/*.rs" scope_filter: has_ancestor: Cargo.toml level: info fix: file_trim_trailing_whitespace: {}rust-sources-no-bidi
Section titled "rust-sources-no-bidi"- kind:
no_bidi_controls - level:
error - when:
facts.has_rust - policy: https://trojansource.codes/
Trojan Source (CVE-2021-42574): bidi override chars in Rust sources are rejected.
- id: rust-sources-no-bidi when: facts.has_rust kind: no_bidi_controls paths: "**/*.rs" scope_filter: has_ancestor: Cargo.toml level: error message: "Trojan Source (CVE-2021-42574): bidi override chars in Rust sources are rejected." policy_url: "https://trojansource.codes/" rust-sources-no-zero-width
Section titled "rust-sources-no-zero-width"- kind:
no_zero_width_chars - level:
error - when:
facts.has_rust
Zero-width characters in Rust sources are rejected (review hazard).
- id: rust-sources-no-zero-width when: facts.has_rust kind: no_zero_width_chars paths: "**/*.rs" scope_filter: has_ancestor: Cargo.toml level: error message: "Zero-width characters in Rust sources are rejected (review hazard)."rust-no-merge-markers-in-manifests
Section titled "rust-no-merge-markers-in-manifests"- kind:
no_merge_conflict_markers - level:
error - when:
facts.has_rust
- id: rust-no-merge-markers-in-manifests when: facts.has_rust kind: no_merge_conflict_markers paths: ["Cargo.toml", "**/Cargo.toml" , "Cargo.lock", "**/Cargo.lock" ] scope_filter: has_ancestor: Cargo.toml level: errorThe when: clauses above read these facts. Each is resolved once per run; alint facts prints what they resolved to in your repository.
facts: - id: has_rust any_file_exists: [Cargo.toml, "**/Cargo.toml" ]Customize
Section titled "Customize"Every rule here can be overridden by id from your own .alint.yml: change its level, or set level: off to drop it. An id that doesn't exist is an error at config load, so a typo can't silently pass.
extends: - alint://bundled/rust@v1 rules: - id: rust-cargo-toml-exists level: off - id: rust-cargo-lock-exists level: errorTo take only part of the ruleset, filter it where you extend it with only: or except::
extends: - url: alint://bundled/rust@v1 except: [rust-cargo-toml-exists]Bundled rulesets covers versioning and how rulesets combine.
Source
Section titled "Source"The full ruleset definition, comments included, is committed at crates/alint-dsl/rulesets/v1/rust.yml in the alint repo.