Fix ICE for iter_overeager_cloned

This commit is contained in:
Takayuki Nakata 2022-03-29 21:51:37 +09:00
parent 6206086dd5
commit c22b7b8814
4 changed files with 31 additions and 11 deletions

View File

@ -1,11 +1,12 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet;
use clippy_utils::ty::{get_iterator_item_ty, is_copy};
use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy};
use itertools::Itertools;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::sym;
use std::ops::Not;
use super::ITER_OVEREAGER_CLONED;
@ -20,9 +21,16 @@ pub(super) fn check<'tcx>(
map_arg: &[hir::Expr<'_>],
) {
// Check if it's iterator and get type associated with `Item`.
let inner_ty = match get_iterator_item_ty(cx, cx.typeck_results().expr_ty_adjusted(recv)) {
Some(ty) => ty,
_ => return,
let inner_ty = if_chain! {
if let Some(iterator_trait_id) = cx.tcx.get_diagnostic_item(sym::Iterator);
let recv_ty = cx.typeck_results().expr_ty(recv);
if implements_trait(cx, recv_ty, iterator_trait_id, &[]);
if let Some(inner_ty) = get_iterator_item_ty(cx, cx.typeck_results().expr_ty_adjusted(recv));
then {
inner_ty
} else {
return;
}
};
match inner_ty.kind() {

View File

@ -1,5 +1,6 @@
// run-rustfix
#![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
#![allow(dead_code)]
fn main() {
let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@ -43,3 +44,8 @@ fn main() {
// Should probably stay as it is.
let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
}
// #8527
fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
x.cloned().flatten()
}

View File

@ -1,5 +1,6 @@
// run-rustfix
#![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
#![allow(dead_code)]
fn main() {
let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@ -45,3 +46,8 @@ fn main() {
// Should probably stay as it is.
let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
}
// #8527
fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
x.cloned().flatten()
}

View File

@ -1,5 +1,5 @@
error: called `cloned().last()` on an `Iterator`. It may be more efficient to call `last().cloned()` instead
--> $DIR/iter_overeager_cloned.rs:7:29
--> $DIR/iter_overeager_cloned.rs:8:29
|
LL | let _: Option<String> = vec.iter().cloned().last();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().last().cloned()`
@ -7,13 +7,13 @@ LL | let _: Option<String> = vec.iter().cloned().last();
= note: `-D clippy::iter-overeager-cloned` implied by `-D warnings`
error: called `cloned().next()` on an `Iterator`. It may be more efficient to call `next().cloned()` instead
--> $DIR/iter_overeager_cloned.rs:9:29
--> $DIR/iter_overeager_cloned.rs:10:29
|
LL | let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().chain(vec.iter()).next().cloned()`
error: called `cloned().count()` on an `Iterator`. It may be more efficient to call `count()` instead
--> $DIR/iter_overeager_cloned.rs:11:20
--> $DIR/iter_overeager_cloned.rs:12:20
|
LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").count()`
@ -21,25 +21,25 @@ LL | let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
= note: `-D clippy::redundant-clone` implied by `-D warnings`
error: called `cloned().take(...)` on an `Iterator`. It may be more efficient to call `take(...).cloned()` instead
--> $DIR/iter_overeager_cloned.rs:13:21
--> $DIR/iter_overeager_cloned.rs:14:21
|
LL | let _: Vec<_> = vec.iter().cloned().take(2).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().take(2).cloned()`
error: called `cloned().skip(...)` on an `Iterator`. It may be more efficient to call `skip(...).cloned()` instead
--> $DIR/iter_overeager_cloned.rs:15:21
--> $DIR/iter_overeager_cloned.rs:16:21
|
LL | let _: Vec<_> = vec.iter().cloned().skip(2).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().skip(2).cloned()`
error: called `cloned().nth(...)` on an `Iterator`. It may be more efficient to call `nth(...).cloned()` instead
--> $DIR/iter_overeager_cloned.rs:17:13
--> $DIR/iter_overeager_cloned.rs:18:13
|
LL | let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").nth(2).cloned()`
error: called `cloned().flatten()` on an `Iterator`. It may be more efficient to call `flatten().cloned()` instead
--> $DIR/iter_overeager_cloned.rs:19:13
--> $DIR/iter_overeager_cloned.rs:20:13
|
LL | let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))]
| _____________^