about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/lib.register_all.rs2
-rw-r--r--clippy_lints/src/lib.register_correctness.rs2
-rw-r--r--clippy_lints/src/lib.register_lints.rs2
-rw-r--r--clippy_lints/src/lib.rs2
-rw-r--r--clippy_lints/src/methods/mod.rs44
-rw-r--r--clippy_lints/src/methods/unit_hash.rs29
-rw-r--r--clippy_lints/src/unit_hash.rs78
7 files changed, 76 insertions, 83 deletions
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs
index aad6a1af200..e51ce0fa254 100644
--- a/clippy_lints/src/lib.register_all.rs
+++ b/clippy_lints/src/lib.register_all.rs
@@ -208,6 +208,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(methods::SUSPICIOUS_MAP),
     LintId::of(methods::SUSPICIOUS_SPLITN),
     LintId::of(methods::UNINIT_ASSUMED_INIT),
+    LintId::of(methods::UNIT_HASH),
     LintId::of(methods::UNNECESSARY_FILTER_MAP),
     LintId::of(methods::UNNECESSARY_FIND_MAP),
     LintId::of(methods::UNNECESSARY_FOLD),
@@ -326,7 +327,6 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(types::VEC_BOX),
     LintId::of(unicode::INVISIBLE_CHARACTERS),
     LintId::of(uninit_vec::UNINIT_VEC),
-    LintId::of(unit_hash::UNIT_HASH),
     LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
     LintId::of(unit_types::LET_UNIT_VALUE),
     LintId::of(unit_types::UNIT_ARG),
diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs
index 9d69d4acc90..d30e69b2240 100644
--- a/clippy_lints/src/lib.register_correctness.rs
+++ b/clippy_lints/src/lib.register_correctness.rs
@@ -42,6 +42,7 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
     LintId::of(methods::NONSENSICAL_OPEN_OPTIONS),
     LintId::of(methods::SUSPICIOUS_SPLITN),
     LintId::of(methods::UNINIT_ASSUMED_INIT),
+    LintId::of(methods::UNIT_HASH),
     LintId::of(methods::ZST_OFFSET),
     LintId::of(minmax::MIN_MAX),
     LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
@@ -67,7 +68,6 @@ store.register_group(true, "clippy::correctness", Some("clippy_correctness"), ve
     LintId::of(transmute::WRONG_TRANSMUTE),
     LintId::of(unicode::INVISIBLE_CHARACTERS),
     LintId::of(uninit_vec::UNINIT_VEC),
-    LintId::of(unit_hash::UNIT_HASH),
     LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
     LintId::of(unit_types::UNIT_CMP),
     LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs
index a2a81052070..8aa1810fbd5 100644
--- a/clippy_lints/src/lib.register_lints.rs
+++ b/clippy_lints/src/lib.register_lints.rs
@@ -358,6 +358,7 @@ store.register_lints(&[
     methods::SUSPICIOUS_MAP,
     methods::SUSPICIOUS_SPLITN,
     methods::UNINIT_ASSUMED_INIT,
+    methods::UNIT_HASH,
     methods::UNNECESSARY_FILTER_MAP,
     methods::UNNECESSARY_FIND_MAP,
     methods::UNNECESSARY_FOLD,
@@ -558,7 +559,6 @@ store.register_lints(&[
     unicode::NON_ASCII_LITERAL,
     unicode::UNICODE_NOT_NFC,
     uninit_vec::UNINIT_VEC,
-    unit_hash::UNIT_HASH,
     unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
     unit_types::LET_UNIT_VALUE,
     unit_types::UNIT_ARG,
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index e0b6ded0b58..71ba3f18da8 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -371,7 +371,6 @@ mod types;
 mod undocumented_unsafe_blocks;
 mod unicode;
 mod uninit_vec;
-mod unit_hash;
 mod unit_return_expecting_ord;
 mod unit_types;
 mod unnamed_address;
@@ -582,7 +581,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(blocks_in_if_conditions::BlocksInIfConditions));
     store.register_late_pass(|| Box::new(unicode::Unicode));
     store.register_late_pass(|| Box::new(uninit_vec::UninitVec));
-    store.register_late_pass(|| Box::new(unit_hash::UnitHash));
     store.register_late_pass(|| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
     store.register_late_pass(|| Box::new(strings::StringAdd));
     store.register_late_pass(|| Box::new(implicit_return::ImplicitReturn));
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index a47081d8752..ce10b64c948 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -78,6 +78,7 @@ mod string_extend_chars;
 mod suspicious_map;
 mod suspicious_splitn;
 mod uninit_assumed_init;
+mod unit_hash;
 mod unnecessary_filter_map;
 mod unnecessary_fold;
 mod unnecessary_iter_cloned;
@@ -2832,6 +2833,45 @@ declare_clippy_lint! {
     "use of sort() when sort_unstable() is equivalent"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Detects `().hash(_)`.
+    ///
+    /// ### Why is this bad?
+    /// Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use std::hash::Hash;
+    /// # use std::collections::hash_map::DefaultHasher;
+    /// # enum Foo { Empty, WithValue(u8) }
+    /// # use Foo::*;
+    /// # let mut state = DefaultHasher::new();
+    /// # let my_enum = Foo::Empty;
+    /// match my_enum {
+    /// 	Empty => ().hash(&mut state),
+    /// 	WithValue(x) => x.hash(&mut state),
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::hash::Hash;
+    /// # use std::collections::hash_map::DefaultHasher;
+    /// # enum Foo { Empty, WithValue(u8) }
+    /// # use Foo::*;
+    /// # let mut state = DefaultHasher::new();
+    /// # let my_enum = Foo::Empty;
+    /// match my_enum {
+    /// 	Empty => 0_u8.hash(&mut state),
+    /// 	WithValue(x) => x.hash(&mut state),
+    /// }
+    /// ```
+    #[clippy::version = "1.58.0"]
+    pub UNIT_HASH,
+    correctness,
+    "hashing a unit value, which does nothing"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Option<RustcVersion>,
@@ -2949,6 +2989,7 @@ impl_lint_pass!(Methods => [
     RANGE_ZIP_WITH_LEN,
     REPEAT_ONCE,
     STABLE_SORT_PRIMITIVE,
+    UNIT_HASH,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -3258,6 +3299,9 @@ impl Methods {
                     get_last_with_len::check(cx, expr, recv, arg);
                 },
                 ("get_or_insert_with", [arg]) => unnecessary_lazy_eval::check(cx, expr, recv, arg, "get_or_insert"),
+                ("hash", [arg]) => {
+                    unit_hash::check(cx, expr, recv, arg);
+                },
                 ("is_file", []) => filetype_is_file::check(cx, expr, recv),
                 ("is_digit", [radix]) => is_digit_ascii_radix::check(cx, expr, recv, radix, self.msrv),
                 ("is_none", []) => check_is_some_is_none(cx, expr, recv, false),
diff --git a/clippy_lints/src/methods/unit_hash.rs b/clippy_lints/src/methods/unit_hash.rs
new file mode 100644
index 00000000000..3c7955bc469
--- /dev/null
+++ b/clippy_lints/src/methods/unit_hash.rs
@@ -0,0 +1,29 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_trait_method;
+use clippy_utils::source::snippet;
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_span::sym;
+
+use super::UNIT_HASH;
+
+pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'tcx Expr<'_>, arg: &'tcx Expr<'_>) {
+    if is_trait_method(cx, expr, sym::Hash) && cx.typeck_results().expr_ty(recv).is_unit() {
+        span_lint_and_then(
+            cx,
+            UNIT_HASH,
+            expr.span,
+            "this call to `hash` on the unit type will do nothing",
+            |diag| {
+                diag.span_suggestion(
+                    expr.span,
+                    "remove the call to `hash` or consider using",
+                    format!("0_u8.hash({})", snippet(cx, arg.span, ".."),),
+                    Applicability::MaybeIncorrect,
+                );
+                diag.note("the implementation of `Hash` for `()` is a no-op");
+            },
+        );
+    }
+}
diff --git a/clippy_lints/src/unit_hash.rs b/clippy_lints/src/unit_hash.rs
deleted file mode 100644
index 88ca0cb20a1..00000000000
--- a/clippy_lints/src/unit_hash.rs
+++ /dev/null
@@ -1,78 +0,0 @@
-use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet;
-use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::sym;
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Detects `().hash(_)`.
-    ///
-    /// ### Why is this bad?
-    /// Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.
-    ///
-    /// ### Example
-    /// ```rust
-    /// # use std::hash::Hash;
-    /// # use std::collections::hash_map::DefaultHasher;
-    /// # enum Foo { Empty, WithValue(u8) }
-    /// # use Foo::*;
-    /// # let mut state = DefaultHasher::new();
-    /// # let my_enum = Foo::Empty;
-    /// match my_enum {
-    /// 	Empty => ().hash(&mut state),
-    /// 	WithValue(x) => x.hash(&mut state),
-    /// }
-    /// ```
-    /// Use instead:
-    /// ```rust
-    /// # use std::hash::Hash;
-    /// # use std::collections::hash_map::DefaultHasher;
-    /// # enum Foo { Empty, WithValue(u8) }
-    /// # use Foo::*;
-    /// # let mut state = DefaultHasher::new();
-    /// # let my_enum = Foo::Empty;
-    /// match my_enum {
-    /// 	Empty => 0_u8.hash(&mut state),
-    /// 	WithValue(x) => x.hash(&mut state),
-    /// }
-    /// ```
-    #[clippy::version = "1.58.0"]
-    pub UNIT_HASH,
-    correctness,
-    "hashing a unit value, which does nothing"
-}
-declare_lint_pass!(UnitHash => [UNIT_HASH]);
-
-impl<'tcx> LateLintPass<'tcx> for UnitHash {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if_chain! {
-            if let ExprKind::MethodCall(name_ident, args, _) = &expr.kind;
-            if name_ident.ident.name == sym::hash;
-            if let [recv, state_param] = args;
-            if cx.typeck_results().expr_ty(recv).is_unit();
-            then {
-                span_lint_and_then(
-                    cx,
-                    UNIT_HASH,
-                    expr.span,
-                    "this call to `hash` on the unit type will do nothing",
-                    |diag| {
-                        diag.span_suggestion(
-                            expr.span,
-                            "remove the call to `hash` or consider using",
-                            format!(
-                                "0_u8.hash({})",
-                                snippet(cx, state_param.span, ".."),
-                            ),
-                            Applicability::MaybeIncorrect,
-                        );
-                        diag.note("the implementation of `Hash` for `()` is a no-op");
-                    }
-                );
-            }
-        }
-    }
-}