Skip to content

Commit c0a5693

Browse files
committed
Auto merge of #8602 - giraffate:fix_ice_for_iter_overeager_cloned, r=llogiq
Fix ICE for `iter_overeager_cloned` Fix #8527 changelog: Fix ICE for [`iter_overeager_cloned`]
2 parents fe7254f + c22b7b8 commit c0a5693

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

clippy_lints/src/methods/iter_overeager_cloned.rs

Lines changed: 12 additions & 4 deletions
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, is_copy};
3+
use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy};
44
use itertools::Itertools;
55
use rustc_errors::Applicability;
66
use rustc_hir as hir;
77
use rustc_lint::LateContext;
88
use rustc_middle::ty;
9+
use rustc_span::sym;
910
use std::ops::Not;
1011

1112
use super::ITER_OVEREAGER_CLONED;
@@ -20,9 +21,16 @@ pub(super) fn check<'tcx>(
2021
map_arg: &[hir::Expr<'_>],
2122
) {
2223
// Check if it's iterator and get type associated with `Item`.
23-
let inner_ty = match get_iterator_item_ty(cx, cx.typeck_results().expr_ty_adjusted(recv)) {
24-
Some(ty) => ty,
25-
_ => return,
24+
let inner_ty = if_chain! {
25+
if let Some(iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
26+
let recv_ty = cx.typeck_results().expr_ty(recv);
27+
if implements_trait(cx, recv_ty, iterator_trait_id, &[]);
28+
if let Some(inner_ty) = get_iterator_item_ty(cx, cx.typeck_results().expr_ty_adjusted(recv));
29+
then {
30+
inner_ty
31+
} else {
32+
return;
33+
}
2634
};
2735

2836
match inner_ty.kind() {

tests/ui/iter_overeager_cloned.fixed

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// run-rustfix
22
#![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
3+
#![allow(dead_code)]
34

45
fn main() {
56
let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@@ -43,3 +44,8 @@ fn main() {
4344
// Should probably stay as it is.
4445
let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
4546
}
47+
48+
// #8527
49+
fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
50+
x.cloned().flatten()
51+
}

tests/ui/iter_overeager_cloned.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// run-rustfix
22
#![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
3+
#![allow(dead_code)]
34

45
fn main() {
56
let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@@ -45,3 +46,8 @@ fn main() {
4546
// Should probably stay as it is.
4647
let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
4748
}
49+
50+
// #8527
51+
fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
52+
x.cloned().flatten()
53+
}

tests/ui/iter_overeager_cloned.stderr

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
11
error: called `cloned().last()` on an `Iterator`. It may be more efficient to call `last().cloned()` instead
2-
--> $DIR/iter_overeager_cloned.rs:7:29
2+
--> $DIR/iter_overeager_cloned.rs:8:29
33
|
44
LL | let _: Option<String> = vec.iter().cloned().last();
55
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().last().cloned()`
66
|
77
= note: `-D clippy::iter-overeager-cloned` implied by `-D warnings`
88

99
error: called `cloned().next()` on an `Iterator`. It may be more efficient to call `next().cloned()` instead
10-
--> $DIR/iter_overeager_cloned.rs:9:29
10+
--> $DIR/iter_overeager_cloned.rs:10:29
1111
|
1212
LL | let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();
1313
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().chain(vec.iter()).next().cloned()`
1414

1515
error: called `cloned().count()` on an `Iterator`. It may be more efficient to call `count()` instead
16-
--> $DIR/iter_overeager_cloned.rs:11:20
16+
--> $DIR/iter_overeager_cloned.rs:12:20
1717
|
1818
LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
1919
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").count()`
2020
|
2121
= note: `-D clippy::redundant-clone` implied by `-D warnings`
2222

2323
error: called `cloned().take(...)` on an `Iterator`. It may be more efficient to call `take(...).cloned()` instead
24-
--> $DIR/iter_overeager_cloned.rs:13:21
24+
--> $DIR/iter_overeager_cloned.rs:14:21
2525
|
2626
LL | let _: Vec<_> = vec.iter().cloned().take(2).collect();
2727
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().take(2).cloned()`
2828

2929
error: called `cloned().skip(...)` on an `Iterator`. It may be more efficient to call `skip(...).cloned()` instead
30-
--> $DIR/iter_overeager_cloned.rs:15:21
30+
--> $DIR/iter_overeager_cloned.rs:16:21
3131
|
3232
LL | let _: Vec<_> = vec.iter().cloned().skip(2).collect();
3333
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().skip(2).cloned()`
3434

3535
error: called `cloned().nth(...)` on an `Iterator`. It may be more efficient to call `nth(...).cloned()` instead
36-
--> $DIR/iter_overeager_cloned.rs:17:13
36+
--> $DIR/iter_overeager_cloned.rs:18:13
3737
|
3838
LL | let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2);
3939
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").nth(2).cloned()`
4040

4141
error: called `cloned().flatten()` on an `Iterator`. It may be more efficient to call `flatten().cloned()` instead
42-
--> $DIR/iter_overeager_cloned.rs:19:13
42+
--> $DIR/iter_overeager_cloned.rs:20:13
4343
|
4444
LL | let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))]
4545
| _____________^

0 commit comments

Comments
 (0)