Skip to content

Commit 7c5487d

Browse files
committed
Auto merge of #7562 - dswij:filter-next-false-positive, r=xFrednet
Fix false positive on `filter_next` fixes #7561 changelog: Fix false positive on [`filter_next`] when a method does not implement `Iterator`
2 parents b4d76b4 + 91b598a commit 7c5487d

File tree

3 files changed

+18
-3
lines changed

3 files changed

+18
-3
lines changed

clippy_lints/src/methods/filter_next.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
2-
use clippy_utils::is_trait_method;
32
use clippy_utils::source::snippet;
3+
use clippy_utils::ty::implements_trait;
44
use rustc_errors::Applicability;
55
use rustc_hir as hir;
66
use rustc_lint::LateContext;
@@ -16,7 +16,10 @@ pub(super) fn check<'tcx>(
1616
filter_arg: &'tcx hir::Expr<'_>,
1717
) {
1818
// lint if caller of `.filter().next()` is an Iterator
19-
if is_trait_method(cx, expr, sym::Iterator) {
19+
let recv_impls_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
20+
implements_trait(cx, cx.typeck_results().expr_ty(recv), id, &[])
21+
});
22+
if recv_impls_iterator {
2023
let msg = "called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
2124
`.find(..)` instead";
2225
let filter_snippet = snippet(cx, filter_arg.span, "..");

tests/ui/auxiliary/option_helpers.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,12 @@ impl IteratorFalsePositives {
5353
self.foo as usize
5454
}
5555
}
56+
57+
#[derive(Copy, Clone)]
58+
pub struct IteratorMethodFalsePositives;
59+
60+
impl IteratorMethodFalsePositives {
61+
pub fn filter(&self, _s: i32) -> std::vec::IntoIter<i32> {
62+
unimplemented!();
63+
}
64+
}

tests/ui/methods.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use std::ops::Mul;
3232
use std::rc::{self, Rc};
3333
use std::sync::{self, Arc};
3434

35-
use option_helpers::IteratorFalsePositives;
35+
use option_helpers::{IteratorFalsePositives, IteratorMethodFalsePositives};
3636

3737
struct Lt<'a> {
3838
foo: &'a u32,
@@ -131,6 +131,9 @@ fn filter_next() {
131131
// Check that we don't lint if the caller is not an `Iterator`.
132132
let foo = IteratorFalsePositives { foo: 0 };
133133
let _ = foo.filter().next();
134+
135+
let foo = IteratorMethodFalsePositives {};
136+
let _ = foo.filter(42).next();
134137
}
135138

136139
fn main() {

0 commit comments

Comments
 (0)