# Clippy и rustfmt

> Официальные инструменты Rust — rustfmt форматирует код по единому стилю, Clippy проверяет его сотнями линтов на ошибки, неидиоматичные конструкции и проблемы производительности.

Источник: https://llmdocs.ru/wiki/clippy-rustfmt/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Язык**: Rust
- **rustfmt**: форматтер, команда cargo fmt
- **Clippy**: линтер, команда cargo clippy; более 750 линтов
- **Установка**: компоненты rustup (rustfmt, clippy)
- **Настройки**: rustfmt.toml, clippy.toml, [lints] в Cargo.toml
- **Интеграция**: rust-analyzer, pre-commit, CI
**rustfmt** и **Clippy** — официальные инструменты экосистемы [Rust](https://llmdocs.ru/wiki/rust.md), которые устанавливаются вместе с компилятором через rustup. **rustfmt** автоматически приводит код к единому стилю, описанному в Rust Style Guide, а **Clippy** — линтер с сотнями проверок, который находит ошибки, неидиоматичный код и упущенные возможности для оптимизации. Оба запускаются через [Cargo](https://llmdocs.ru/wiki/cargo.md) одной командой и стали обязательной частью CI почти любого Rust-проекта.[1][3]

## rustfmt

rustfmt следует официальному руководству по стилю Rust:[4] четыре пробела, максимальная ширина строки 100 символов, завершающие запятые в многострочных списках, упорядоченные импорты.

```bash
rustup component add rustfmt
cargo fmt              # отформатировать весь проект
cargo fmt --check      # только проверить (для CI), код возврата ≠ 0 при расхождениях
```

В отличие от [gofmt](https://llmdocs.ru/wiki/gofmt-govet.md), у rustfmt есть настройки в файле `rustfmt.toml` — но сообщество рекомендует почти ничего не менять, чтобы код всех проектов выглядел одинаково.[6]

```toml
# rustfmt.toml
edition = "2024"
max_width = 100
# nightly-опции:
# imports_granularity = "Crate"
# group_imports = "StdExternalCrate"
```

Многие опции доступны только в nightly-версии. Отдельный фрагмент можно исключить атрибутом `#[rustfmt::skip]` — например, вручную выровненную матрицу. Стиль привязан к **редакции** языка (style edition), поэтому обновление rustfmt не переформатирует код неожиданно.

## Clippy

Clippy проверяет код на уровне, недоступном обычным предупреждениям компилятора. Название — отсылка к скрепке-помощнику из Microsoft Office.[1]

```bash
rustup component add clippy
cargo clippy                              # проверить
cargo clippy --all-targets --all-features -- -D warnings   # строго, для CI
cargo clippy --fix                        # применить автоматические исправления
```

### Группы линтов

Линты разделены на группы с разным уровнем по умолчанию:[2]

| Группа | По умолчанию | Что ловит |
|---|---|---|
| `correctness` | ошибка | почти наверняка баги |
| `suspicious` | предупреждение | подозрительный код |
| `style` | предупреждение | неидиоматичное написание |
| `complexity` | предупреждение | излишне сложный код |
| `perf` | предупреждение | лишние аллокации и копирования |
| `pedantic` | выкл. | строгие, иногда спорные проверки |
| `restriction` | выкл. | запреты под политику проекта (`unwrap_used`, `print_stdout`) |
| `nursery` | выкл. | экспериментальные линты |
| `cargo` | выкл. | проблемы метаданных Cargo.toml |

### Примеры

```rust
// clippy::len_zero — используйте is_empty()
if v.len() == 0 { }

// clippy::needless_range_loop — итерируйтесь напрямую
for i in 0..v.len() { println!("{}", v[i]); }

// clippy::redundant_clone — лишнее копирование
let s2 = s.clone(); drop(s);

// clippy::manual_map
let y = match x { Some(v) => Some(v + 1), None => None };   // → x.map(|v| v + 1)

// clippy::unwrap_used (restriction) — запрет unwrap в продакшен-коде
let n: i32 = input.parse().unwrap();
```

Линты особенно полезны новичкам: они подсказывают идиомы — `if let`, итераторы, `?` вместо ручного `match` (см. [Обработка ошибок в Rust (Result, ?)](https://llmdocs.ru/wiki/rust-errors.md)) — и объясняют их ссылкой на документацию.

## Настройка

С Rust 1.74 уровни линтов удобно задавать прямо в `Cargo.toml` — для одного крейта или для всего workspace:[5][7]

```toml
[lints.rust]
unsafe_code = "forbid"

[lints.clippy]
pedantic = { level = "warn", priority = -1 }
unwrap_used = "deny"
undocumented_unsafe_blocks = "deny"
module_name_repetitions = "allow"
```

Отдельные места можно разрешить атрибутом с объяснением:

```rust
#[expect(clippy::too_many_arguments, reason = "API повторяет C-функцию")]
fn ffi_wrapper(a: i32, b: i32, c: i32, d: i32, e: i32, f: i32, g: i32, h: i32) {}
```

Атрибут `#[expect]` (стабилен с Rust 1.81) лучше `#[allow]`: он выдаст предупреждение, если подавляемый линт перестал срабатывать и подавление стало ненужным. Числовые пороги (например, допустимая когнитивная сложность) задаются в `clippy.toml`.

Линт `undocumented_unsafe_blocks` требует комментарий `// SAFETY:` у каждого `unsafe`-блока — это стандартная практика для [Unsafe Rust](https://llmdocs.ru/wiki/unsafe-rust.md).

## В CI и редакторе

Типичный набор шагов в [GitHub Actions](https://llmdocs.ru/wiki/github-actions.md) или [GitLab CI](https://llmdocs.ru/wiki/gitlab-ci.md):

```bash
cargo fmt --all --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
```

Флаг `-D warnings` превращает предупреждения в ошибки, чтобы новый код не добавлял замечаний. Версию инструментов стоит закрепить файлом `rust-toolchain.toml`: каждый релиз Rust добавляет новые линты, и без фиксации сборка может внезапно «покраснеть». В редакторе rust-analyzer умеет запускать Clippy вместо `cargo check` при сохранении и показывать замечания прямо в коде.

## Аналоги

Похожую пару в Go образуют gofmt и go vet со staticcheck, в Python — [Ruff](https://llmdocs.ru/wiki/ruff.md) (линтер и форматтер в одном), в JavaScript — Prettier и ESLint. Как и Ruff, Clippy умеет автоматически исправлять многие замечания.

## См. также

- [gofmt и go vet](https://llmdocs.ru/wiki/gofmt-govet.md)
- [Cargo и crates.io](https://llmdocs.ru/wiki/cargo.md)
- [Ruff](https://llmdocs.ru/wiki/ruff.md)
- [Макросы Rust](https://llmdocs.ru/wiki/rust-macros.md)

## Источники

1. [Clippy documentation](https://doc.rust-lang.org/clippy/)
2. [Clippy lints list](https://rust-lang.github.io/rust-clippy/master/index.html)
3. [rustfmt — GitHub](https://github.com/rust-lang/rustfmt)
4. [Rust Style Guide](https://doc.rust-lang.org/style-guide/)
5. [Cargo Book — The [lints] section](https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section)
6. [rustfmt — Configuring Rustfmt](https://rust-lang.github.io/rustfmt/)
7. [Rust Blog — Announcing Rust 1.74.0 (lint configuration through Cargo)](https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html)
