Rust はコンパイラ自体が強力な品質ゲートとして機能しますが、それだけに留まらず、エコシステムには多種多様な品質保証ツールが揃っています。本記事では lint・フォーマット・テスト・カバレッジ・セキュリティ監査など、実務で使える主要ツールを体系的に解説します。

Linter / フォーマッター

rustfmt

rustfmt は Rust 公式のコードフォーマッターです。cargo fmt で呼び出せます。

# フォーマット適用
cargo fmt

# 差分確認のみ(CI 向け)
cargo fmt --check

プロジェクトルートに rustfmt.toml を置くことでスタイルをカスタマイズできます。

# rustfmt.toml
edition = "2021"
max_width = 100
imports_granularity = "Crate"
group_imports = "StdExternalCrate"

CI では cargo fmt --check を組み込み、フォーマット差分があればビルドを失敗させるのが定石です。

Clippy

Clippy は Rust 公式の lint ツールで、200 以上のリントルールを持ちます。cargo clippy で実行します。

# 基本実行
cargo clippy

# すべての lint を警告として扱う
cargo clippy -- -W clippy::all

# pedantic カテゴリも有効化
cargo clippy -- -W clippy::pedantic

Clippy のリントはカテゴリで分類されており、重要度や目的が異なります。

カテゴリ 内容
correctness バグになり得るコード(デフォルト: deny)
suspicious 意図が疑わしいパターン
style 慣用的な書き方への誘導
perf パフォーマンス改善の提案
pedantic 厳格なスタイル(オプトイン)
nursery 実験的なリント(オプトイン)

#[allow(...)]#[warn(...)] でファイル・関数単位の制御もできますが、deny をファイル先頭に書いてプロジェクト全体を厳格に保つ方法も有効です。

#![deny(clippy::all)]
#![warn(clippy::pedantic)]

型システムと静的解析

Rust コンパイラ(rustc)

Rust のコンパイラ自体が最強の静的解析ツールです。型安全・所有権チェック・借用チェッカーにより、null 参照・データ競合・メモリ解放後使用といったバグをコンパイル時に検出します。cargo check を使うとリンクをスキップして型チェックだけを高速に実行できます。

# リンクせず型チェックのみ(通常の build より速い)
cargo check

rust-analyzer

rust-analyzer は LSP(Language Server Protocol)実装で、エディタでのリアルタイム解析を担います。インレイヒント・コード補完・リファクタリング支援などを提供し、VS Code や Neovim などの主要エディタで利用できます。

インストールは rustup component add rust-analyzer で完了します。

MIRI

MIRI は Rust の MIR(Mid-level Intermediate Representation)インタプリタで、unsafe コードの未定義動作を検出します。通常のコンパイラでは検出できない out-of-bounds アクセスや不正なポインタ操作をランタイムで発見します。

rustup component add miri
cargo miri test

unsafe を多用するクレートや FFI 境界を持つコードの検証に特に効果的です。

テスト

cargo test

Rust 標準のテストランナーです。ユニットテスト・統合テスト・ドクテストをすべてカバーします。

// ユニットテスト(同じファイル内)
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_add() {
        assert_eq!(add(2, 3), 5);
    }

    #[test]
    #[should_panic(expected = "overflow")]
    fn test_overflow() {
        add(i32::MAX, 1);
    }
}

統合テストは tests/ ディレクトリに配置します。ドクテストはドキュメントコメント内の ```rust ブロックが自動的にテストとして実行されます。

# すべてのテストを実行
cargo test

# 特定のテスト名でフィルタ
cargo test test_add

# ドクテストのみ
cargo test --doc

cargo-nextest

cargo-nextest は高速な並列テストランナーです。標準の cargo test より大幅に速く、テスト結果の表示も見やすくなります。

cargo install cargo-nextest
cargo nextest run

JUnit XML 形式でレポート出力できるため、CI との統合にも向いています。

proptest / quickcheck

proptestquickcheckプロパティベーステストを実現するクレートです。手動でテストケースを書く代わりに「この性質が常に成り立つ」という命題をランダム生成された入力で検証します。

use proptest::prelude::*;

proptest! {
    #[test]
    fn test_sort_idempotent(mut v: Vec<i32>) {
        v.sort();
        let first = v.clone();
        v.sort();
        prop_assert_eq!(first, v);
    }
}

エッジケースの発見に特に強く、境界値を手動で列挙する手間を省けます。

カバレッジ

cargo-llvm-cov

cargo-llvm-cov は LLVM のソースベースカバレッジ計測を使ったカバレッジツールです。HTML レポートの生成や lcov 形式への出力が可能です。

cargo install cargo-llvm-cov
rustup component add llvm-tools-preview

# HTML レポートをブラウザで開く
cargo llvm-cov --open

# lcov 形式で出力(Codecov 等と連携)
cargo llvm-cov --lcov --output-path lcov.info

tarpaulin

tarpaulin は Linux 向けのカバレッジツールです。ptrace を利用するため Linux 専用ですが、設定が簡単です。

cargo install cargo-tarpaulin
cargo tarpaulin --out Html

macOS では cargo-llvm-cov を選ぶのが現状の定番です。

セキュリティ・依存関係

cargo-audit

cargo-auditRustSec Advisory Database を参照して、依存クレートの既知脆弱性をスキャンします。

cargo install cargo-audit
cargo audit

CI に組み込んでおくと、依存関係に新しい脆弱性が登録されたタイミングでビルドを失敗させられます。

cargo-deny

cargo-deny は依存関係のポリシー管理ツールです。使用を禁止するライセンス・クレート・重複バージョンの制限をルールとして定義します。

cargo install cargo-deny
cargo deny check

設定ファイル deny.toml でポリシーを宣言します。

# deny.toml
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-2-Clause"]

[bans]
multiple-versions = "warn"

cargo-geiger

cargo-geiger は依存グラフ全体にわたる unsafe コードの使用量を可視化します。unsafe を完全に排除できなくても、どのクレートがリスクの源かを把握するのに役立ちます。

cargo install cargo-geiger
cargo geiger

その他の便利ツール

cargo-expand

cargo-expand はマクロを展開した後のコードを表示します。デバッグや、derive マクロが生成するコードの確認に欠かせません。

cargo install cargo-expand
cargo expand

cargo-udeps

cargo-udepsCargo.toml に宣言されているが実際には使われていない依存クレートを検出します。nightly ツールチェーンが必要です。

cargo install cargo-udeps
cargo +nightly udeps

cargo-bloat

cargo-bloat はバイナリサイズに対してどの関数・クレートが寄与しているかを分析します。リリースビルドのサイズ最適化に使います。

cargo install cargo-bloat
cargo bloat --release --crates

CI 統合のヒント

justfile での組み合わせ

just はシンプルなタスクランナーで、複数ツールの呼び出しを一元管理できます。

# justfile
check:
    cargo fmt --check
    cargo clippy -- -D warnings
    cargo test
    cargo audit

ci: check
    cargo llvm-cov --lcov --output-path lcov.info

GitHub Actions 設定例

name: CI
on: [push, pull_request]

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy, llvm-tools-preview

      - name: Format check
        run: cargo fmt --check

      - name: Clippy
        run: cargo clippy -- -D warnings

      - name: Test
        run: cargo test

      - name: Audit
        run: |
          cargo install cargo-audit
          cargo audit

      - name: Coverage
        run: |
          cargo install cargo-llvm-cov
          cargo llvm-cov --lcov --output-path lcov.info

dtolnay/rust-toolchain アクションを使うと rust-toolchain.toml のバージョン固定とも相性が良く、components でまとめてインストールできます。

まとめ

Rust の品質保証ツールを整理すると次の通りです。

目的 ツール
フォーマット rustfmt(cargo fmt
Lint Clippy(cargo clippy
型チェック(高速) cargo check
Unsafe 検証 MIRI
テスト cargo test、cargo-nextest
プロパティテスト proptest、quickcheck
カバレッジ cargo-llvm-cov、tarpaulin
脆弱性スキャン cargo-audit
依存ポリシー cargo-deny
unsafe 可視化 cargo-geiger
マクロ展開確認 cargo-expand
未使用依存 cargo-udeps
バイナリ解析 cargo-bloat

コンパイラ自体の強力な保証を基盤にしつつ、これらのツールを CI に組み込むことで、Rust プロジェクトの品質を高い水準に維持できます。まずは cargo fmt --check + cargo clippy -- -D warnings + cargo test + cargo audit の 4 つを GitHub Actions に追加するところから始めてみてください。