clippy yang kita jalankan di Chapter sebelumnya melaporkan tiga lint dengan nama panjang seperti clippy::needless_range_loop — dan itu baru tiga dari ratusan lint yang tersedia. Menghadapi daftar sepanjang itu, dua pertanyaan praktis muncul: lint mana saja yang aktif saat kita menjalankan cargo clippy tanpa argumen, dan bagaimana mengatur kelompoknya tanpa menyebut nama satu per satu? Jawabannya adalah sistem kategori: clippy mengelompokkan seluruh lint ke dalam kelompok seperti correctness, style, dan pedantic, dan setiap kelompok bisa dinyalakan, dimatikan, atau dinaikkan levelnya dengan satu flag. Chapter ini memetakan kelompok tersebut, menjelaskan empat level lint, lalu membuktikannya dengan program yang bersih secara bawaan tetapi berisik ketika standar pedantic diterapkan.
Masalah: Ratusan Lint Tanpa Peta #
Setiap lint memeriksa satu pola spesifik, dan jumlah pola terus bertambah tiap rilis. Mengatur ratusan nama satu per satu jelas tidak praktis. Kategori memecahkan masalah skala ini: satu nama kelompok seperti clippy::pedantic merujuk seluruh lint anggotanya sekaligus, dan flag baris perintah atau atribut level crate dapat menyetel seluruh kelompok dalam satu penulisan.
Kategori Lint dan Status Bawaannya #
Peta lengkap kelompok lint clippy beserta maknanya:
| Kategori | Makna | Status bawaan |
|---|---|---|
clippy::correctness | Kode yang hampir pasti salah atau tidak berguna | Aktif sebagai error |
clippy::suspicious | Kode yang mungkin sumber bug, tetapi belum pasti | Aktif sebagai warning |
clippy::style | Kode yang sebaiknya ditulis lebih idiomatik | Aktif sebagai warning |
clippy::complexity | Kode yang melakukan hal sederhana dengan cara rumit | Aktif sebagai warning |
clippy::perf | Kode yang bisa ditulis agar berjalan lebih cepat | Aktif sebagai warning |
clippy::pedantic | Lint ketat yang kadang ber-false positive | Tidak aktif |
clippy::nursery | Lint baru yang masih dikembangkan | Tidak aktif |
clippy::restriction | Lint untuk memaksakan gaya atau pola tertentu | Tidak aktif |
Lima kelompok pertama — correctness, suspicious, style, complexity, dan perf — tergabung dalam payung clippy::all dan itulah yang berjalan ketika kita memanggil cargo clippy polos. Kelompok correctness bahkan diperlakukan sebagai error: potensi kepastian salah layak menghentikan kompilasi, bukan sekadar dikeluhkan. Tiga kelompok terakhir sengaja tidak aktif karena karakternya: pedantic terlalu berisik untuk sebagian besar proyek, nursery masih mentah, dan restriction adalah kumpulan aturan opsional untuk tim yang ingin kebijakan sangat spesifik.
Mekanisme: Empat Level Lint dan Flag-nya #
Setiap lint — per nama maupun per kategori — hidup pada satu dari empat level: allow membuat lint diam sepenuhnya, warn melaporkan temuan sebagai warning, deny melaporkan temuan sebagai error yang menggagalkan build, dan forbid setara deny tetapi tidak bisa diturunkan lagi oleh atribut #[allow] di dalam kode. Level bisa disetel dari dua tempat: flag pada baris perintah (-A untuk allow, -W untuk warn, -D untuk deny, -F untuk forbid) yang ditulis setelah --, atau atribut di dalam source code seperti #![warn(clippy::pedantic)] di level crate dan #[allow(clippy::len_zero)] di level item. Semua yang muncul setelah -- diteruskan dari Cargo ke clippy — itulah mengapa penulisannya adalah cargo clippy -- -W clippy::pedantic.
Contoh: Kode Bersih yang Belum Lolos Pedantic #
Buat proyek baru dan isi src/main.rs dengan program pembulatan berat pesanan:
fn main() {
let total_gram = 2_450.7;
let gram_bulat = total_gram as i32;
println!("Total pesanan: {} gram", gram_bulat);
}Jalankan clippy polos terlebih dahulu:
cargo clippyOutput yang Dihasilkan:
Checking kasbon v0.1.0 (/tmp/w5b-lint)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.06sTidak ada warning — program ini lolos seluruh kelompok bawaan. Sekarang naikkan standar pemeriksaan dengan mengaktifkan pedantic:
cargo clippy -- -W clippy::pedanticOutput yang Dihasilkan:
Checking kasbon v0.1.0 (/tmp/w5b-lint)
warning: casting `f64` to `i32` may truncate the value
--> src/main.rs:3:22
|
3 | let gram_bulat = total_gram as i32;
| ^^^^^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.99.0/index.html#cast_possible_truncation
= note: `-W clippy::cast-possible-truncation` implied by `-W clippy::pedantic`
= help: to override `-W clippy::pedantic` add `#[allow(clippy::cast_possible_truncation)]`
warning: variables can be used directly in the `format!` string
--> src/main.rs:4:5
|
4 | println!("Total pesanan: {} gram", gram_bulat);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.99.0/index.html#uninlined_format_args
= note: `-W clippy::uninlined-format-args` implied by `-W clippy::pedantic`
help: change this to
|
4 - println!("Total pesanan: {} gram", gram_bulat);
4 + println!("Total pesanan: {gram_bulat} gram");
|
warning: `kasbon` (bin "kasbon") generated 2 warnings (run `cargo clippy --fix --bin "kasbon" -p kasbon -- -W clippy::pedantic` to apply 1 suggestion)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03sDua warning baru muncul, keduanya anggota pedantic yang tidak aktif pada pemanggilan polos. Mari kita bedah laporan tersebut baris per baris:
- Baris 3 (
let gram_bulat = total_gram as i32;): memicu lintclippy::cast_possible_truncation— cast darif64kei32membuang pecahan (2450.7menjadi2450) dan nilai di luar jangkauani32bisa terpotong lebih parah. Baris catatan= note: -W clippy::cast-possible-truncation implied by -W clippy::pedanticmenegaskan lint ini menyala karena kelompokpedanticyang kita aktifkan, bukan karena status bawaannya. - Baris 4 (
println!("Total pesanan: {} gram", gram_bulat);): memicu lintclippy::uninlined_format_args— variabel bisa ditulis langsung di dalam string format sebagai{gram_bulat}alih-alih{}diikuti argumen di akhir pemanggilan. Sarannya ditampilkan sebagai diff siap pakai: ganti baris ini denganprintln!("Total pesanan: {gram_bulat} gram");. - Baris
generated 2 warnings ... to apply 1 suggestion: satu dari dua saran bersifat machine-applicable (uninlined_format_args), satu lagi (cast_possible_truncation) menuntut keputusan manusia. - Perbandingan dua laporan: kedua pemanggilan memeriksa source code yang sama persis, tetapi hasilnya berbeda — kategori bukan properti kode, melainkan cakupan pemeriksaan yang kita pilih.
Menjinakkan Satu Lint dengan #[allow] #
Cast pada program kita memang disengaja — label berat selalu ditulis sebagai bilangan bulat. Solusi yang tepat bukan mematikan seluruh pedantic, melainkan menandai keputusan itu pada baris yang bersangkutan:
fn main() {
let total_gram = 2_450.7;
// pembulatan ke bawah memang disengaja untuk label berat
#[allow(clippy::cast_possible_truncation)]
let gram_bulat = total_gram as i32;
println!("Total pesanan: {gram_bulat} gram");
}Jalankan kembali dengan standar yang sama:
cargo clippy -- -W clippy::pedanticOutput yang Dihasilkan:
Checking kasbon v0.1.0 (/tmp/w5b-lint)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.03sAtribut #[allow(clippy::cast_possible_truncation)] hanya mematikan satu lint pada satu statement, dan komentar di atasnya menjelaskan alasan keputusannya — pembaca berikutnya tahu bahwa cast tersebut dipikirkan matang. Perhatikan juga println! yang kini memakai format inline {gram_bulat}: saran kedua kita terima karena memang lebih ringkas. Inilah pola kerja yang sehat dengan clippy — saran dinilai satu per satu, diterima bila benar, dan ditolak dengan alasan tertulis bila ada konteks yang tidak diketahui linter.
Menaikkan Level: dari Warning ke Error #
Level deny mengubah kelompok apa pun menjadi penjaga gerbang. Bila cast yang disengaja tadi kita hapus atributnya dan jalankan perintah berikut:
cargo clippy -- -D clippy::cast_possible_truncationOutput yang Dihasilkan:
Checking kasbon v0.1.0 (/tmp/w5b-lint)
error: casting `f64` to `i32` may truncate the value
--> src/main.rs:3:22
|
3 | let gram_bulat = total_gram as i32;
| ^^^^^^^^^^^^^^^^^
|
= help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.99.0/index.html#cast_possible_truncation
= note: requested on the command line with `-D clippy::cast-possible-truncation`
error: could not compile `kasbon` (bin "kasbon") due to 1 previous errorTemuan yang sama kini berstatus error — build gagal dan perintah keluar dengan kode 101, sama seperti kompilasi yang gagal. Baris requested on the command line with -D ... mencatat sumber deny-nya: flag baris perintah kita, bukan level bawaan. Flag -D warnings yang kita pakai di Chapter sebelumnya bekerja dengan cara yang sama persis, hanya saja kelompoknya adalah seluruh warning.
Flag baris perintah harus diketik setiap kali clippy dijalankan, sehingga penyetelan permanen lebih baik ditaruh di manifest. Cargo mendukung table [lints] di Cargo.toml — baris berikut mengaktifkan pedantic sebagai warning untuk seluruh proyek tanpa flag apa pun:
[lints.clippy]
pedantic = "warn"Dengan table ini, pemanggilan cargo clippy polos menghasilkan dua warning pedantic yang sama seperti pemanggilan berflag di atas — konfigurasi menyatu dengan proyek dan ikut tercommit ke repository.
Ringkasan #
clippy mengelompokkan lint ke dalam kategori: correctness, suspicious, style, complexity, dan perf aktif bawaan (correctness bahkan sebagai error), sementara pedantic, nursery, dan restriction menunggu diaktifkan dengan -W, atribut crate, atau konfigurasi [lints] di Cargo.toml. Empat level — allow, warn, deny, forbid — mengatur keparahan, dan #[allow] pada item bisa menjinakkan satu lint disertai alasan tertulis. Program yang bersih secara bawaan bisa berisik di bawah pedantic; keputusan menerapkan standar yang lebih tinggi adalah keputusan tim. Satu langkah tersisa: memastikan seluruh disiplin ini berjalan tanpa bergantung pada kesadaran manusia — lewat CI.