Project-wide formatting and lint configuration for the matek_tgzt Cargo workspace, modeled on the rust-project-template. Two pieces: a workspace-root rustfmt.toml and a [workspace.lints.*] block in the root Cargo.toml, with each member crate opting in via [lints] workspace = true.

For Agents

  • Scope: workspace-root rustfmt.toml + root Cargo.toml [workspace.lints]; member crates wire in with [lints] workspace = true.
  • Toolchain: the rustfmt config needs nightly — run cargo +nightly fmt. The clippy/rust/rustdoc lints work on stable.
  • Policy stance: deny-by-default. Lots of deny levels. Expect to need scoped #[allow(...)] for tests, main, and prototyping.
  • Source of truth: mirrors https://github.com/mracsko/rust-project-template — when in doubt, diff against that template.

rustfmt.toml (workspace root)

Keys set, mirroring the template:

KeyValueNotes
max_width200Wide lines allowed (vs default 100)
imports_granularity"Crate"Nightly-only. Merge imports from the same crate into one use
imports_layout"Vertical"Nightly-only. One import per line inside braces
group_imports"StdExternalCrate"Nightly-only. Three groups: std/core/alloc, external crates, then crate/self/super
format_code_in_doc_commentstrueNightly-only. Reformat ```rust code blocks in doc comments
wrap_commentstrueNightly-only. Wrap long // and /// comments to max_width

Nightly rustfmt required

Five of the six keys above are unstable rustfmt options. Running plain cargo fmt on a stable toolchain will not apply them (older rustfmt silently ignores unknown keys; newer versions emit a warning). Always format with:

cargo +nightly fmt

Consider pinning this in a rust-toolchain.toml or CI step so the formatting is reproducible.

Cargo.toml — [workspace.lints.*] (workspace root)

The root Cargo.toml gains a [workspace.lints] section split across four tables. The general pattern from the template: deny whole lint groups as a baseline, then cherry-pick individual lints (mostly from clippy’s pedantic / restriction / style groups, which are not enabled wholesale).

[workspace.lints.clippy]

  • Baseline groups denied: correctness, perf, suspicious (these are deny-worthy across the board).
  • Cherry-picked individual lints denied (a representative set — the template enables more):
    • unwrap_used — no .unwrap()
    • expect_used — no .expect(...)
    • panic — no panic!()
    • indexing_slicing — no a[i] / a[i..j] that can panic; use .get()
    • print_stdout — no println! / print! (use a logger / proper output) — note: this currently flags packages/app/src/main.rs
    • undocumented_unsafe_blocks — every unsafe { } needs a // SAFETY: comment
    • …plus other pedantic/restriction/style picks per the template.

[workspace.lints.rust]

  • Edition-compatibility lint groups denied (e.g. rust_2018_compatibility, rust_2021_compatibility, rust_2024_compatibility — keeps the codebase clean against future edition migrations).
  • rust_2018_idioms denied — modern idioms enforced.
  • unsafe_code denied — no unsafe blocks allowed at all (must be explicitly #[allow]-ed per-module if ever needed).

[workspace.lints.cargo]

  • Cargo lints enabled per the template (e.g. catching things like negative_feature_names, wildcard_dependencies, redundant feature names). Keeps Cargo.toml manifests tidy across the workspace.

[workspace.lints.rustdoc]

  • broken_intra_doc_links — denied (doc links must resolve)
  • private_intra_doc_links — denied
  • missing_crate_level_docs — denied (every crate needs a //! crate-level doc)
  • …plus other rustdoc lints per the template (invalid HTML, bare URLs, etc.).

Member crate wiring

Every member crate’s Cargo.toml opts into the shared policy:

[lints]
workspace = true

So packages/app/Cargo.toml carries that block, and any future packages/<name>/Cargo.toml must too. Without it, a crate silently ignores the workspace lint policy.

Consequences / gotchas

println! in main.rs trips clippy::print_stdout

The current packages/app/src/main.rs is fn main() { println!("Hello, world!"); }. With print_stdout denied, cargo clippy will error on it. Either #[allow(clippy::print_stdout)] on main, or replace the hello-world body with real logic / a logger once development starts.

How to relax a lint locally

Don’t weaken [workspace.lints] for one-off needs. Instead scope an allow at the narrowest level:

#[allow(clippy::unwrap_used)]
fn test_helper() { /* ... */ }

Common spots that legitimately need allows: #[cfg(test)] modules (unwrap_used, expect_used, panic, indexing_slicing), fn main (print_stdout), and quick prototypes.

Keep in sync with the template

This config is a snapshot of https://github.com/mracsko/rust-project-template. If you’re adding/removing lints, check the template first so the project doesn’t drift from its reference. The template tends to add lints over time.

  • matek_tgzt — project overview
  • LOG — matek_tgzt activity log
  • TOPICS — matek_tgzt topic index