Skip to content

Commit

Permalink
Auto merge of rust-lang#7562 - dswij:filter-next-false-positive, r=xF…
Browse files Browse the repository at this point in the history
…rednet

Fix false positive on `filter_next`

fixes rust-lang#7561

changelog: Fix false positive on [`filter_next`] when a method does not implement `Iterator`
  • Loading branch information
bors committed Aug 13, 2021
2 parents b4d76b4 + 91b598a commit 7c5487d
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 3 deletions.
7 changes: 5 additions & 2 deletions clippy_lints/src/methods/filter_next.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
use clippy_utils::is_trait_method;
use clippy_utils::source::snippet;
use clippy_utils::ty::implements_trait;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
Expand All @@ -16,7 +16,10 @@ pub(super) fn check<'tcx>(
filter_arg: &'tcx hir::Expr<'_>,
) {
// lint if caller of `.filter().next()` is an Iterator
if is_trait_method(cx, expr, sym::Iterator) {
let recv_impls_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
implements_trait(cx, cx.typeck_results().expr_ty(recv), id, &[])
});
if recv_impls_iterator {
let msg = "called `filter(..).next()` on an `Iterator`. This is more succinctly expressed by calling \
`.find(..)` instead";
let filter_snippet = snippet(cx, filter_arg.span, "..");
Expand Down
9 changes: 9 additions & 0 deletions tests/ui/auxiliary/option_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,12 @@ impl IteratorFalsePositives {
self.foo as usize
}
}

#[derive(Copy, Clone)]
pub struct IteratorMethodFalsePositives;

impl IteratorMethodFalsePositives {
pub fn filter(&self, _s: i32) -> std::vec::IntoIter<i32> {
unimplemented!();
}
}
5 changes: 4 additions & 1 deletion tests/ui/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use std::ops::Mul;
use std::rc::{self, Rc};
use std::sync::{self, Arc};

use option_helpers::IteratorFalsePositives;
use option_helpers::{IteratorFalsePositives, IteratorMethodFalsePositives};

struct Lt<'a> {
foo: &'a u32,
Expand Down Expand Up @@ -131,6 +131,9 @@ fn filter_next() {
// Check that we don't lint if the caller is not an `Iterator`.
let foo = IteratorFalsePositives { foo: 0 };
let _ = foo.filter().next();

let foo = IteratorMethodFalsePositives {};
let _ = foo.filter(42).next();
}

fn main() {
Expand Down

0 comments on commit 7c5487d

Please sign in to comment.