Skip to content

Commit 4665853

Browse files
committed
Do lint only if the values is cloned, but not copied
1 parent 9bcef5d commit 4665853

File tree

3 files changed

+15
-9
lines changed

3 files changed

+15
-9
lines changed

clippy_lints/src/methods/iter_overeager_cloned.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::snippet;
3-
use clippy_utils::ty::implements_trait;
3+
use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy};
44
use rustc_errors::Applicability;
55
use rustc_hir as hir;
66
use rustc_lint::LateContext;
7+
use rustc_middle::ty;
78
use rustc_span::sym;
89

910
use super::ITER_OVEREAGER_CLONED;
@@ -17,6 +18,17 @@ pub(super) fn check<'tcx>(
1718
name: &str,
1819
map_arg: &[hir::Expr<'_>],
1920
) {
21+
let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
22+
let inner_ty = match get_iterator_item_ty(cx, recv_ty) {
23+
Some(ty) => ty,
24+
_ => return,
25+
};
26+
27+
match inner_ty.kind() {
28+
ty::Ref(_, ty, _) if is_copy(cx, ty) => return,
29+
_ => {},
30+
};
31+
2032
// lint if callee is an Iterator
2133
let recv_impls_iterator = cx.tcx.get_diagnostic_item(sym::Iterator).map_or(false, |id| {
2234
implements_trait(cx, cx.typeck_results().expr_ty(recv), id, &[])

tests/ui/iter_overeager_cloned.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,5 @@ fn main() {
4141
let _ = vec.iter().cloned().any(|x| x.len() == 1);
4242

4343
// Should probably stay as it is.
44-
let _ = [0, 1, 2, 3, 4].iter().take(10).cloned();
44+
let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
4545
}

tests/ui/iter_overeager_cloned.stderr

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,5 @@ LL ~ let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))]
5454
LL ~ .iter().flatten().cloned();
5555
|
5656

57-
error: called `cloned().take(...)` on an `Iterator`. It may be more efficient to call`.take(...).cloned()` instead
58-
--> $DIR/iter_overeager_cloned.rs:46:13
59-
|
60-
LL | let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `[0, 1, 2, 3, 4].iter().take(10).cloned()`
62-
63-
error: aborting due to 8 previous errors
57+
error: aborting due to 7 previous errors
6458

0 commit comments

Comments
 (0)