TL;DR

  • Clippy の警告が出ない状態を保つ。
  • Clippy は CI でも実行する。
  • Clippy の lint の一覧を読むと、Rust らしい書き方を深く理解できる。

内容

https://effective-rust.com/clippy.html

Clippy の警告の種類

Clippy は、Rust の書き方について、次のようなカテゴリの警告を出す(参考: https://doc.rust-lang.org/stable/clippy/lints.html )。

  • 正確さ(correctness): よくあるプログラミング上の誤り
  • Rust らしさ(idiom): 標準的な Rust のスタイルに従っていない書き方
  • 簡潔さ(concision): もっと短く書ける書き方
  • 性能(performance): 避けられる処理やメモリ確保
  • 読みやすさ(readability): 人間がもっと読みやすく、理解しやすくなる書き方

たとえば次のコードはコンパイルできるが、Clippy はエラーにする。

pub fn circle_area(radius: f64) -> f64 {
    let pi = 3.14;
    pi * radius * radius
}
error: approximate value of `f{32, 64}::consts::PI` found
 --> src/main.rs:2:14
  |
2 |     let pi = 3.14;
  |              ^^^^
  |
  = help: consider using the constant directly
  = note: `#[deny(clippy::approx_constant)]` on by default

指摘どおり std::f64::consts::PI を使えば直る。

警告への向き合い方

Clippy の警告には、内容を説明した Web ページへのリンクが付いている。そのページには、なぜそのコードが悪いのかが書かれているので、自分のコードに当てはまるかを判断できる。項目によっては偽陽性の可能性にも触れている。Rust らしい書き方を深く理解したいなら、この一覧を読むとよい。

警告が自分のコードに当てはまらないと判断したら、#[allow(...)] で無効にできる。#![allow(...)] と書けばクレート全体で無効になる。ただし、偽陽性かどうかを議論するより、リファクタリングに労力を使ったほうがよい。

コードに対して Clippy の警告が出ないようにしよう

コードを直すにせよ警告を無効にするにせよ、警告が出ない状態を保てば、新しい警告が出たときに気づける。CI でも Clippy を実行する(項目32)。

Clippy で検出できる他の項目

本書の項目の多くは、Clippy で検出できる。

項目検出する状況lint
項目1引数や構造体のフィールドに bool が多いfn_params_excessive_bools、struct_excessive_bools
項目3Result から Option への不要な変換、unwrap_or_default で書けるコード、エラーを呼び出し元に返さないコードok_expect、unwrap_or_default、unwrap_in_result
項目5From ではなく Into を実装しているfrom_over_into
項目5as の利用(デフォルトでは無効)。from で書ける、値が切り捨てられる、ラップアラウンドする、精度が落ちる、符号が失われる、すべての ascast_lossless、cast_possible_truncation、cast_possible_wrap、cast_precision_loss、cast_sign_loss、as_conversions
項目8ヒープ上のコレクションを Box で持つ、コレクションの要素を Box で持つ、Box への参照を取るbox_collection、vec_box、borrowed_box
項目9Iterator のメソッドの組み合わせをもっと簡潔に書ける多数
項目10Ord と PartialOrd の実装が矛盾する、PartialEq::ne を実装している(項目13)、Hash と Eq の実装が矛盾する、Copy と Clone の実装が一致しないderived_ord_xor_partial_ord、partialeq_ne_impl、derived_hash_with_manual_eq、expl_impl_clone_on_copy
項目18panic! や expect などを使っている多数
項目21依存ライブラリのバージョンを * で指定しているwildcard_dependencies
項目23ワイルドカードインポートを使っているwildcard_imports
項目24、項目25同じクレートの複数のバージョンが依存グラフにあるmultiple_crate_versions
項目26否定形の feature 名(no_std など)、クレートを使うことだけを表す feature 名(use-crate-x など)negative_feature_names、redundant_feature_names
項目27ドキュメンテーションコメントに panic! や unsafe の説明がないmissing_panics_doc、missing_safety_doc、undocumented_unsafe_blocks

キーワード