Skip to content

Commit ecf660f

Browse files
committed
Simplify code for this lint
1 parent 04663f4 commit ecf660f

File tree

2 files changed

+40
-61
lines changed

2 files changed

+40
-61
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::snippet;
3-
use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy};
3+
use clippy_utils::ty::{get_iterator_item_ty, is_copy};
4+
use itertools::Itertools;
45
use rustc_errors::Applicability;
56
use rustc_hir as hir;
67
use rustc_lint::LateContext;
78
use rustc_middle::ty;
8-
use rustc_span::sym;
9+
use std::ops::Not;
910

1011
use super::ITER_OVEREAGER_CLONED;
1112
use crate::redundant_clone::REDUNDANT_CLONE;
@@ -19,72 +20,46 @@ pub(super) fn check<'tcx>(
1920
map_arg: &[hir::Expr<'_>],
2021
) {
2122
let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
23+
// Check if it's iterator and get type associated with `Item`.
2224
let inner_ty = match get_iterator_item_ty(cx, recv_ty) {
2325
Some(ty) => ty,
2426
_ => return,
2527
};
2628

2729
match inner_ty.kind() {
28-
ty::Ref(_, ty, _) if is_copy(cx, ty) => return,
29-
_ => {},
30+
ty::Ref(_, ty, _) if !is_copy(cx, ty) => {},
31+
_ => return,
3032
};
3133

32-
// lint if callee is an Iterator
33-
let recv_impls_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
34-
implements_trait(cx, cx.typeck_results().expr_ty(recv), id, &[])
35-
});
36-
if recv_impls_iterator {
37-
let (lint, msg) = match name {
38-
"count" => (
39-
REDUNDANT_CLONE,
40-
format!(
41-
"called `cloned().{}()` on an `Iterator`. It may be more efficient to call\
42-
`.{}()` instead",
43-
name, name
44-
),
45-
),
46-
_ if map_arg.is_empty() => (
47-
ITER_OVEREAGER_CLONED,
48-
format!(
49-
"called `cloned().{}()` on an `Iterator`. It may be more efficient to call\
50-
`.{}().cloned()` instead",
51-
name, name
52-
),
53-
),
54-
_ => (
55-
ITER_OVEREAGER_CLONED,
56-
format!(
57-
"called `cloned().{}(...)` on an `Iterator`. It may be more efficient to call\
58-
`.{}(...).cloned()` instead",
59-
name, name
60-
),
61-
),
62-
};
34+
let (lint, msg, preserve_clopned) = match name {
35+
"count" => (REDUNDANT_CLONE, false),
36+
_ => (ITER_OVEREAGER_CLONED, true),
37+
};
38+
let wildcard_params = map_arg.is_empty().not().then(|| "...").unwrap_or_default();
39+
let msg = format!(
40+
"called `cloned().{}({})` on an `Iterator`. It may be more efficient to call\
41+
`.{}({}){}` instead",
42+
name,
43+
wildcard_params,
44+
name,
45+
wildcard_params,
46+
preserve_clopned.then(|| ".cloned()").unwrap_or_default(),
47+
);
6348

64-
let iter_snippet = snippet(cx, recv.span, "..");
65-
span_lint_and_sugg(
66-
cx,
67-
lint,
68-
expr.span,
69-
&msg,
70-
"try this",
71-
match name {
72-
"count" => {
73-
format!("{}.{}()", iter_snippet, name)
74-
},
75-
_ if map_arg.is_empty() => {
76-
format!("{}.{}().cloned()", iter_snippet, name)
77-
},
78-
_ => {
79-
format!(
80-
"{}.{}({}).cloned()",
81-
iter_snippet,
82-
name,
83-
snippet(cx, map_arg[0].span, "..")
84-
)
85-
},
86-
},
87-
Applicability::MachineApplicable,
88-
);
89-
}
49+
let iter_snippet = snippet(cx, recv.span, "..");
50+
span_lint_and_sugg(
51+
cx,
52+
lint,
53+
expr.span,
54+
&msg,
55+
"try this",
56+
format!(
57+
"{}.{}({}){}",
58+
iter_snippet,
59+
name,
60+
map_arg.iter().map(|a| snippet(cx, a.span, "..")).join(", "),
61+
preserve_clopned.then(|| ".cloned()").unwrap_or_default(),
62+
),
63+
Applicability::MachineApplicable,
64+
);
9065
}

clippy_lints/src/methods/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,10 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
23022302
string_extend_chars::check(cx, expr, recv, arg);
23032303
extend_with_drain::check(cx, expr, recv, arg);
23042304
},
2305+
(name @ "filter", args @ []) => match method_call!(recv) {
2306+
Some(("cloned", [recv2], _)) => iter_overeager_cloned::check(cx, expr, recv2, name, args),
2307+
_ => {},
2308+
},
23052309
("filter_map", [arg]) => {
23062310
unnecessary_filter_map::check(cx, expr, arg);
23072311
filter_map_identity::check(cx, expr, arg, span);

0 commit comments

Comments
 (0)