From a6c4eaa93c7400450facd0eb0580e4d641f2e297 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sun, 30 Dec 2018 02:43:56 +0100 Subject: [PATCH] random_state lint --- CHANGELOG.md | 1 + README.md | 2 +- clippy_lints/src/lib.rs | 3 ++ clippy_lints/src/random_state.rs | 48 ++++++++++++++++++++++++++++++++ clippy_lints/src/utils/paths.rs | 1 + tests/ui/random_state.rs | 19 +++++++++++++ tests/ui/random_state.stderr | 28 +++++++++++++++++++ 7 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 clippy_lints/src/random_state.rs create mode 100644 tests/ui/random_state.rs create mode 100644 tests/ui/random_state.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index efa637b185c..b5c8feb8ac6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -814,6 +814,7 @@ All notable changes to this project will be documented in this file. [`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast [`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names [`question_mark`]: https://rust-lang.github.io/rust-clippy/master/index.html#question_mark +[`random_state`]: https://rust-lang.github.io/rust-clippy/master/index.html#random_state [`range_minus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_minus_one [`range_plus_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_plus_one [`range_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#range_step_by_zero diff --git a/README.md b/README.md index 626b589b5f3..be24f1be827 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. -[There are 290 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) +[There are 291 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html) We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you: diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 27905b91750..0aa9ff5985f 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -180,6 +180,7 @@ pub mod precedence; pub mod ptr; pub mod ptr_offset_with_cast; pub mod question_mark; +pub mod random_state; pub mod ranges; pub mod redundant_clone; pub mod redundant_field_names; @@ -484,6 +485,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { reg.register_late_lint_pass(box ptr_offset_with_cast::Pass); reg.register_late_lint_pass(box redundant_clone::RedundantClone); reg.register_late_lint_pass(box slow_vector_initialization::Pass); + reg.register_late_lint_pass(box random_state::Pass); reg.register_lint_group("clippy::restriction", Some("clippy_restriction"), vec![ arithmetic::FLOAT_ARITHMETIC, @@ -1023,6 +1025,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) { fallible_impl_from::FALLIBLE_IMPL_FROM, mutex_atomic::MUTEX_INTEGER, needless_borrow::NEEDLESS_BORROW, + random_state::RANDOM_STATE, redundant_clone::REDUNDANT_CLONE, unwrap::PANICKING_UNWRAP, unwrap::UNNECESSARY_UNWRAP, diff --git a/clippy_lints/src/random_state.rs b/clippy_lints/src/random_state.rs new file mode 100644 index 00000000000..02abd2e93bd --- /dev/null +++ b/clippy_lints/src/random_state.rs @@ -0,0 +1,48 @@ +use crate::utils::{match_type, paths, span_lint}; +use rustc::hir::Ty; +use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; +use rustc::ty::subst::UnpackedKind; +use rustc::ty::TyKind; +use rustc::{declare_tool_lint, lint_array}; + +/// **What it does:** Checks for usage of `RandomState` +/// +/// **Why is this bad?** Some applications don't need collision prevention +/// which lowers the performance. +/// +/// **Known problems:** None. +/// +/// **Example:** +/// ```rust +/// fn x() { +/// let mut map = std::collections::HashMap::new(); +/// map.insert(3, 4); +/// } +/// ``` +declare_clippy_lint! { + pub RANDOM_STATE, + nursery, + "use of RandomState" +} + +pub struct Pass; + +impl LintPass for Pass { + fn get_lints(&self) -> LintArray { + lint_array!(RANDOM_STATE) + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { + fn check_ty(&mut self, cx: &LateContext<'a, 'tcx>, ty: &Ty) { + if let TyKind::Adt(_, substs) = cx.tables.node_id_to_type(ty.hir_id).sty { + for subst in substs { + if let UnpackedKind::Type(build_hasher) = subst.unpack() { + if match_type(cx, build_hasher, &paths::RANDOM_STATE) { + span_lint(cx, RANDOM_STATE, ty.span, "usage of RandomState"); + } + } + } + } + } +} diff --git a/clippy_lints/src/utils/paths.rs b/clippy_lints/src/utils/paths.rs index 0779d77936f..0ec684e36bc 100644 --- a/clippy_lints/src/utils/paths.rs +++ b/clippy_lints/src/utils/paths.rs @@ -73,6 +73,7 @@ pub const PATH_BUF: [&str; 3] = ["std", "path", "PathBuf"]; pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"]; pub const PTR_NULL: [&str; 2] = ["ptr", "null"]; pub const PTR_NULL_MUT: [&str; 2] = ["ptr", "null_mut"]; +pub const RANDOM_STATE: [&str; 5] = ["std", "collections", "hash", "map", "RandomState"]; pub const RANGE: [&str; 3] = ["core", "ops", "Range"]; pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"]; pub const RANGE_FROM: [&str; 3] = ["core", "ops", "RangeFrom"]; diff --git a/tests/ui/random_state.rs b/tests/ui/random_state.rs new file mode 100644 index 00000000000..31f4b4d49b4 --- /dev/null +++ b/tests/ui/random_state.rs @@ -0,0 +1,19 @@ +#![warn(clippy::random_state)] + +use std::collections::hash_map::RandomState; +use std::collections::hash_map::{DefaultHasher, HashMap}; +use std::hash::{BuildHasherDefault}; + +fn main() { + // Should warn + let mut map = HashMap::new(); + map.insert(3, 4); + let mut map = HashMap::with_hasher(RandomState::new()); + map.insert(true, false); + let _map: HashMap<_, _> = vec![(2, 3)].into_iter().collect(); + let _vec: Vec>; + // Shouldn't warn + let _map: HashMap> = HashMap::default(); + let mut map = HashMap::with_hasher(BuildHasherDefault::::default()); + map.insert("a", "b"); +} diff --git a/tests/ui/random_state.stderr b/tests/ui/random_state.stderr new file mode 100644 index 00000000000..df224bf0c29 --- /dev/null +++ b/tests/ui/random_state.stderr @@ -0,0 +1,28 @@ +error: usage of RandomState + --> $DIR/random_state.rs:9:19 + | +LL | let mut map = HashMap::new(); + | ^^^^^^^^^^^^ + | + = note: `-D clippy::random-state` implied by `-D warnings` + +error: usage of RandomState + --> $DIR/random_state.rs:11:19 + | +LL | let mut map = HashMap::with_hasher(RandomState::new()); + | ^^^^^^^^^^^^^^^^^^^^ + +error: usage of RandomState + --> $DIR/random_state.rs:13:15 + | +LL | let _map: HashMap<_, _> = vec![(2, 3)].into_iter().collect(); + | ^^^^^^^^^^^^^ + +error: usage of RandomState + --> $DIR/random_state.rs:14:19 + | +LL | let _vec: Vec>; + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors +