1 use clippy_utils::diagnostics::span_lint_and_then;
2 use clippy_utils::source::snippet;
3 use rustc_errors::Applicability;
4 use rustc_hir::{Expr, ExprKind};
5 use rustc_lint::{LateContext, LateLintPass};
6 use rustc_session::{declare_lint_pass, declare_tool_lint};
11 /// Detects `().hash(_)`.
13 /// ### Why is this bad?
14 /// Hashing a unit value doesn't do anything as the implementation of `Hash` for `()` is a no-op.
18 /// # use std::hash::Hash;
19 /// # use std::collections::hash_map::DefaultHasher;
20 /// # enum Foo { Empty, WithValue(u8) }
22 /// # let mut state = DefaultHasher::new();
23 /// # let my_enum = Foo::Empty;
25 /// Empty => ().hash(&mut state),
26 /// WithValue(x) => x.hash(&mut state),
31 /// # use std::hash::Hash;
32 /// # use std::collections::hash_map::DefaultHasher;
33 /// # enum Foo { Empty, WithValue(u8) }
35 /// # let mut state = DefaultHasher::new();
36 /// # let my_enum = Foo::Empty;
38 /// Empty => 0_u8.hash(&mut state),
39 /// WithValue(x) => x.hash(&mut state),
42 #[clippy::version = "1.58.0"]
45 "hashing a unit value, which does nothing"
47 declare_lint_pass!(UnitHash => [UNIT_HASH]);
49 impl LateLintPass<'tcx> for UnitHash {
50 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
52 if let ExprKind::MethodCall(name_ident, _, args, _) = &expr.kind;
53 if name_ident.ident.name == sym::hash;
54 if let [recv, state_param] = args;
55 if cx.typeck_results().expr_ty(recv).is_unit();
61 "this call to `hash` on the unit type will do nothing",
65 "remove the call to `hash` or consider using",
68 snippet(cx, state_param.span, ".."),
70 Applicability::MaybeIncorrect,
72 diag.note("the implementation of `Hash` for `()` is a no-op");