about summary refs log tree commit diff
diff options
context:
space:
mode:
authornahuakang <kangnahua@gmail.com>2021-02-03 09:39:35 +0100
committernahuakang <kangnahua@gmail.com>2021-02-03 09:39:35 +0100
commit0f5e71f8f2d42e3eac3e855a83d53899d4da6eb3 (patch)
tree9e6a11d0656ad7461e7c6867e9cab04b5f1ab5e6
parente07cd5b6fe47b1e26f19a1bede7c2e4967cb46d7 (diff)
downloadrust-0f5e71f8f2d42e3eac3e855a83d53899d4da6eb3.tar.gz
rust-0f5e71f8f2d42e3eac3e855a83d53899d4da6eb3.zip
Add additional check on if arg type has iter method
-rw-r--r--clippy_lints/src/loops.rs35
1 files changed, 17 insertions, 18 deletions
diff --git a/clippy_lints/src/loops.rs b/clippy_lints/src/loops.rs
index 23dce283f28..5bfdc98bc6a 100644
--- a/clippy_lints/src/loops.rs
+++ b/clippy_lints/src/loops.rs
@@ -2041,25 +2041,24 @@ fn check_manual_flatten<'tcx>(
                     &mut applicability,
                 );
                 // Determine if `arg` is by reference, an `Iterator`, or implicitly adjusted with `into_iter`
-                let hint = match arg.kind {
-                    ExprKind::AddrOf(_, _, arg_expr) => {
+                let arg_ty = cx.typeck_results().expr_ty(arg);
+                let hint = if arg_ty.is_ref() {
+                    if has_iter_method(cx, arg_ty).is_none() {
+                        return;
+                    } else if let ExprKind::AddrOf(_, _, arg_expr) = arg.kind {
                         format!("{}.iter().flatten()", snippet(cx, arg_expr.span, ".."))
-                    },
-                    ExprKind::MethodCall(_, _, _, _) | ExprKind::Path(QPath::Resolved(None, _)) => {
-                        // Determine if `arg` is `Iterator` or implicitly calls `into_iter`
-                        let arg_ty = cx.typeck_results().expr_ty(arg);
-                        if let Some(id) = get_trait_def_id(cx, &paths::ITERATOR) {
-                            let is_iterator = implements_trait(cx, arg_ty, id, &[]);
-                            if is_iterator {
-                                format!("{}.flatten()", arg_snippet)
-                            } else {
-                                format!("{}.into_iter().flatten()", arg_snippet)
-                            }
-                        } else {
-                            return
-                        }
-                    },
-                    _ => return,
+                    } else {
+                        return;
+                    }
+                } else if let Some(id) = get_trait_def_id(cx, &paths::ITERATOR) {
+                    let is_iterator = implements_trait(cx, arg_ty, id, &[]);
+                    if is_iterator {
+                        format!("{}.flatten()", arg_snippet)
+                    } else {
+                        format!("{}.into_iter().flatten()", arg_snippet)
+                    }
+                } else {
+                    return
                 };
 
                 span_lint_and_sugg(