сеньорчикОткрыть в Telegram
← вся теориятеория к собесу · Экосистема Rust

clippy, rustfmt и miri

Тулинг и сборка

Заключительный блок про инженерную гигиену: линтеры, безопасность зависимостей, фиксация тулчейна, образы для прода. Вопросы простые, но по ответам видно, работал ли человек в команде с CI.

Стержень: у каждой задачи свой инструмент, и они не заменяют друг друга.

// Формулировки: «что делает clippy?», «как следите за уязвимостями?», «зачем rust-toolchain.toml?»

Кто за что отвечает

clippy - линтер идиоматичности: лишний clone, ручной цикл вместо итератора, unwrap там, где просится разбор, подозрительные сравнения. Часть подсказок применяется автоматически через --fix. rustfmt форматирует, и спорить о стиле в ревью больше не приходится.

Безопасность зависимостей - cargo audit по базе RustSec (известные уязвимости и заброшенные крейты) плюс cargo deny для политики: лицензии, дубли версий, разрешённые источники. Неопределённое поведение в unsafe ловит Miri. Всё это отдельные шаги в CI, компилятор ими не занимается.

// Полезная привычка: clippy в CI с deny(warnings) на изменённом коде. Иначе правила расходятся между разработчиками, и линтер превращается в шум.

clippy
линтер идиоматичности поверх проверок компилятора
cargo audit
проверка зависимостей по базе уязвимостей RustSec

Версии тулчейна и сборка образа

rust-toolchain.toml фиксирует версию компилятора и нужные компоненты: у всех разработчиков и в CI одинаковые предупреждения clippy и одинаковое поведение форматирования. Это не то же самое, что rust-version в Cargo.toml - там указывается минимальная поддерживаемая версия для пользователей библиотеки.

Для прода часто нужен маленький образ. Цель x86_64-unknown-linux-musl даёт статический бинарник, который кладётся в scratch или distroless и работает без системных библиотек. Плата - аллокатор musl медленнее на многопоточной нагрузке, и это стоит замерить, а не принять на веру.

// В цикле разработки главный инструмент скорости - cargo check: он останавливается до кодогенерации и потому в разы быстрее полной сборки. На нём же работает rust-analyzer в редакторе.

rust-toolchain.toml
фиксация версии компилятора для проекта
MSRV
minimum supported Rust version: самая старая версия компилятора, на которой крейт обязан собираться

Как отвечать: «Как в проекте следят за уязвимостями в зависимостях?»

Отдельным шагом в CI: cargo audit сверяет Cargo.lock с базой RustSec и сообщает про известные уязвимости и заброшенные крейты. Рядом обычно ставят cargo deny - он добавляет политику по лицензиям, дублирующимся версиям и источникам зависимостей. Компилятор такими проверками не занимается, поэтому без этих шагов проблему просто не увидят. Если уязвимость нашлась в транзитивной зависимости и обновления нет, смотрю, можно ли поднять версию промежуточного крейта, временно закрепить патч через секцию patch или зафиксировать исключение с явным сроком пересмотра.

Ты называешь инструменты, разводишь их роли и отвечаешь на неудобное продолжение - что делать, когда обновления нет. Это уже эксплуатационная зрелость.

На чём валятся

  • Считают, что clippy проверяет безопасность зависимостей.
  • Гоняют линтер локально, но не ставят в CI - правила расходятся между разработчиками.
  • Путают rust-toolchain и rust-version.
  • Берут musl ради размера образа, не замерив влияние аллокатора.
  • Не знают про cargo check и ждут полной сборки ради проверки типов.

Проверьте себя

Пять вопросов из банка по этой подтеме. Всего их 13, остальные разбираются в тренажёре.

  1. #rs_tooling1 / 5
    Зачем в проекте фиксируют версию тулчейна в rust-toolchain.toml?
    A)Чтобы все разработчики и CI собирали проект одним компилятором
    B)Чтобы ускорить сборку за счёт кэша компилятора
    C)Чтобы задать минимальную поддерживаемую версию для пользователей крейта
    D)Чтобы запретить использование нестабильных возможностей языка
    показать ответ и разбор
    +A)Чтобы все разработчики и CI собирали проект одним компилятором

    // разбор: Файл заставляет rustup взять указанную версию и нужные компоненты автоматически: у всех одинаковые предупреждения clippy, одинаковое поведение форматирования и одинаковый набор стабильных возможностей. Минимальная поддерживаемая версия — это отдельное поле rust-version в Cargo.toml, и служит оно другой цели.

  2. #rs_tooling2 / 5
    Как в CI отслеживают уязвимости в зависимостях Rust-проекта?
    A)Скриптом сравнения версий с последними на crates.io
    B)Встроенной проверкой cargo build при сборке в release
    C)Анализом бинарника внешним сканером после сборки
    D)cargo audit по базе RustSec, политика — в cargo deny
    показать ответ и разбор
    +D)cargo audit по базе RustSec, политика — в cargo deny

    // разбор: cargo audit сверяет Cargo.lock с базой RustSec и сообщает про известные уязвимости и заброшенные крейты. cargo deny добавляет правила по лицензиям, дублирующимся версиям и источникам зависимостей. Оба гоняют в CI как отдельный шаг — сам компилятор такими проверками не занимается.

  3. #rs_tooling3 / 5
    Нужен маленький образ для сервиса. Что даёт сборка с musl?
    A)Ускорение работы за счёт более быстрой реализации аллокатора
    B)Статический бинарник для образа без системных библиотек
    C)Уменьшение бинарника вдвое за счёт удаления отладочных символов
    D)Кросс-компиляцию под ARM без дополнительных тулчейнов
    показать ответ и разбор
    +B)Статический бинарник для образа без системных библиотек

    // разбор: Цель x86_64-unknown-linux-musl собирает бинарник без зависимости от glibc, поэтому он кладётся в scratch или distroless и запускается без окружения. Плата — аллокатор musl медленнее на многопоточной нагрузке, и это иногда заметно. Альтернатива — обычная сборка поверх тонкого базового образа с нужными библиотеками.

  4. #rs_tooling4 / 5
    Чем cargo check полезнее cargo build во время разработки?
    A)Он проверяет типы и заимствования без кодогенерации
    B)Он проверяет код без учёта зависимостей проекта
    C)Он собирает только изменившиеся файлы, пропуская остальные
    D)Он запускает тесты вместе с проверкой компиляции
    показать ответ и разбор
    +A)Он проверяет типы и заимствования без кодогенерации

    // разбор: Дольше всего в Rust идёт кодогенерация и оптимизация, а разработчику при правке чаще нужен ответ «типы сходятся, заимствования корректны». cargo check останавливается до кодогенерации и потому в разы быстрее — на нём и построена проверка в редакторе через rust-analyzer. Бинарник он не производит.

  5. #rs_tooling5 / 5
    Что делает cargo fix?
    A)Исправляет форматирование кода по правилам rustfmt во всех файлах
    B)Восстанавливает повреждённый Cargo.lock по манифесту проекта и его зависимостям
    C)Пересобирает проект с нуля, очищая каталог target от старых артефактов
    D)Автоматически применяет исправления, предложенные компилятором и линтами
    показать ответ и разбор
    +D)Автоматически применяет исправления, предложенные компилятором и линтами

    // разбор: Многие предупреждения компилятора и clippy содержат машинно-применимое исправление, и cargo fix раскатывает их по коду. Главное применение — переход на новую редакцию: --edition правит идиомы, которые изменились. Форматированием занимается cargo fmt, очисткой — cargo clean, а lock восстанавливается обычной сборкой.

дальше

Теорию прочитали. Навык ставится повторением

В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.