diff options
| author | Jason Newcomb <jsnewcomb@pm.me> | 2022-06-05 21:41:33 -0400 |
|---|---|---|
| committer | Jason Newcomb <jsnewcomb@pm.me> | 2022-08-19 10:54:55 -0400 |
| commit | bb0584dfb425f6c1a8bef9faad9ee36f0bbc19fb (patch) | |
| tree | 306add229851a46884c5cc50f26d3b22cd0ebdbb | |
| parent | e213b6ee35faec133333e07f962958fbbfe12679 (diff) | |
| download | rust-bb0584dfb425f6c1a8bef9faad9ee36f0bbc19fb.tar.gz rust-bb0584dfb425f6c1a8bef9faad9ee36f0bbc19fb.zip | |
Move `UnitHash` into `Methods` lint pass
| -rw-r--r-- | clippy_lints/src/lib.register_all.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.register_correctness.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.register_lints.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/lib.rs | 2 | ||||
| -rw-r--r-- | clippy_lints/src/methods/mod.rs | 44 | ||||
| -rw-r--r-- | clippy_lints/src/methods/unit_hash.rs | 29 | ||||
| -rw-r--r-- | clippy_lints/src/unit_hash.rs | 78 |
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"); - } - ); - } - } - } -} |
