Skip to content

Commit 56eaa7b

Browse files
missing_iterator_fold: code the lint logic
1 parent 4e8fc93 commit 56eaa7b

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

clippy_lints/src/missing_iterator_fold.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
use rustc_hir::*;
1+
use clippy_utils::diagnostics::span_lint;
2+
use rustc_hir::{AssocItemKind, Impl, Item, ItemKind};
23
use rustc_lint::{LateContext, LateLintPass};
34
use rustc_session::declare_lint_pass;
5+
use rustc_span::sym;
46

57
declare_clippy_lint! {
68
/// ### What it does
@@ -49,4 +51,31 @@ declare_clippy_lint! {
4951

5052
declare_lint_pass!(MissingIteratorFold => [MISSING_ITERATOR_FOLD]);
5153

52-
impl LateLintPass<'_> for MissingIteratorFold {}
54+
impl LateLintPass<'_> for MissingIteratorFold {
55+
fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
56+
if let ItemKind::Impl(Impl {
57+
of_trait: Some(trait_ref),
58+
..
59+
}) = &item.kind
60+
&& let Some(trait_id) = trait_ref.trait_def_id()
61+
{
62+
if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id) {
63+
let has_fold = item
64+
.expect_impl()
65+
.items
66+
.iter()
67+
.filter(|assoc| matches!(assoc.kind, AssocItemKind::Fn { .. }))
68+
.map(|assoc| assoc.ident.name.as_str())
69+
.any(|name| name == "fold");
70+
if !has_fold {
71+
span_lint(
72+
cx,
73+
MISSING_ITERATOR_FOLD,
74+
item.span,
75+
"you are implementing `Iterator` without specializing its `fold` method",
76+
);
77+
}
78+
}
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)