From 6d7072b5fdac1bccc5e8049193fbc1543f3b765e Mon Sep 17 00:00:00 2001 From: lengyijun Date: Thu, 6 Mar 2025 19:29:26 +0800 Subject: [PATCH] extend `needless_collect` Fix https://github.com/rust-lang/rust-clippy/issues/14350 Co-authored-by: Timo <30553356+y21@users.noreply.github.com> --- clippy_lints/src/methods/needless_collect.rs | 33 ++++++++++------ tests/ui/needless_collect.fixed | 4 ++ tests/ui/needless_collect.rs | 4 ++ tests/ui/needless_collect.stderr | 40 +++++++++++--------- 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/methods/needless_collect.rs b/clippy_lints/src/methods/needless_collect.rs index 4f005103d23f..055fdcabdd21 100644 --- a/clippy_lints/src/methods/needless_collect.rs +++ b/clippy_lints/src/methods/needless_collect.rs @@ -38,11 +38,14 @@ pub(super) fn check<'tcx>( Node::Expr(parent) => { check_collect_into_intoiterator(cx, parent, collect_expr, call_span, iter_expr); + let sugg: String; + let mut app; + if let ExprKind::MethodCall(name, _, args @ ([] | [_]), _) = parent.kind { - let mut app = Applicability::MachineApplicable; + app = Applicability::MachineApplicable; let collect_ty = cx.typeck_results().expr_ty(collect_expr); - let sugg: String = match name.ident.name { + sugg = match name.ident.name { sym::len => { if let Some(adt) = collect_ty.ty_adt_def() && matches!( @@ -78,17 +81,23 @@ pub(super) fn check<'tcx>( }, _ => return, }; - - span_lint_and_sugg( - cx, - NEEDLESS_COLLECT, - call_span.with_hi(parent.span.hi()), - NEEDLESS_COLLECT_MSG, - "replace with", - sugg, - app, - ); + } else if let ExprKind::Index(_, index, _) = parent.kind { + app = Applicability::MaybeIncorrect; + let snip = snippet_with_applicability(cx, index.span, "_", &mut app); + sugg = format!("nth({snip}).unwrap()"); + } else { + return; } + + span_lint_and_sugg( + cx, + NEEDLESS_COLLECT, + call_span.with_hi(parent.span.hi()), + NEEDLESS_COLLECT_MSG, + "replace with", + sugg, + app, + ); }, Node::LetStmt(l) => { if let PatKind::Binding(BindingMode::NONE | BindingMode::MUT, id, _, None) = l.pat.kind diff --git a/tests/ui/needless_collect.fixed b/tests/ui/needless_collect.fixed index 842d77dbc8c5..ba1451bf9704 100644 --- a/tests/ui/needless_collect.fixed +++ b/tests/ui/needless_collect.fixed @@ -20,6 +20,10 @@ fn main() { } sample.iter().cloned().any(|x| x == 1); //~^ needless_collect + + let _ = sample.iter().cloned().nth(1).unwrap(); + //~^ needless_collect + // #7164 HashMap's and BTreeMap's `len` usage should not be linted sample.iter().map(|x| (x, x)).collect::>().len(); sample.iter().map(|x| (x, x)).collect::>().len(); diff --git a/tests/ui/needless_collect.rs b/tests/ui/needless_collect.rs index 98d8d27321d2..e054cd01e6f5 100644 --- a/tests/ui/needless_collect.rs +++ b/tests/ui/needless_collect.rs @@ -20,6 +20,10 @@ fn main() { } sample.iter().cloned().collect::>().contains(&1); //~^ needless_collect + + let _ = sample.iter().cloned().collect::>()[1]; + //~^ needless_collect + // #7164 HashMap's and BTreeMap's `len` usage should not be linted sample.iter().map(|x| (x, x)).collect::>().len(); sample.iter().map(|x| (x, x)).collect::>().len(); diff --git a/tests/ui/needless_collect.stderr b/tests/ui/needless_collect.stderr index 00745eb2923c..c77674dc55d4 100644 --- a/tests/ui/needless_collect.stderr +++ b/tests/ui/needless_collect.stderr @@ -20,100 +20,106 @@ LL | sample.iter().cloned().collect::>().contains(&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:27:35 + --> tests/ui/needless_collect.rs:24:36 + | +LL | let _ = sample.iter().cloned().collect::>()[1]; + | ^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `nth(1).unwrap()` + +error: avoid using `collect()` when not needed + --> tests/ui/needless_collect.rs:31:35 | LL | sample.iter().map(|x| (x, x)).collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:29:35 + --> tests/ui/needless_collect.rs:33:35 | LL | sample.iter().map(|x| (x, x)).collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:37:19 + --> tests/ui/needless_collect.rs:41:19 | LL | sample.iter().collect::>().len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:39:19 + --> tests/ui/needless_collect.rs:43:19 | LL | sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:41:28 + --> tests/ui/needless_collect.rs:45:28 | LL | sample.iter().cloned().collect::>().contains(&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == 1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:43:19 + --> tests/ui/needless_collect.rs:47:19 | LL | sample.iter().collect::>().contains(&&1); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &1)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:47:19 + --> tests/ui/needless_collect.rs:51:19 | LL | sample.iter().collect::>().len(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `count()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:49:19 + --> tests/ui/needless_collect.rs:53:19 | LL | sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:55:27 + --> tests/ui/needless_collect.rs:59:27 | LL | let _ = sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:57:27 + --> tests/ui/needless_collect.rs:61:27 | LL | let _ = sample.iter().collect::>().contains(&&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:80:27 + --> tests/ui/needless_collect.rs:84:27 | LL | let _ = sample.iter().collect::>().is_empty(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:82:27 + --> tests/ui/needless_collect.rs:86:27 | LL | let _ = sample.iter().collect::>().contains(&&0); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `any(|x| x == &0)` error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:87:40 + --> tests/ui/needless_collect.rs:91:40 | LL | Vec::::new().extend((0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:89:20 + --> tests/ui/needless_collect.rs:93:20 | LL | foo((0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:91:49 + --> tests/ui/needless_collect.rs:95:49 | LL | bar((0..10).collect::>(), (0..10).collect::>()); | ^^^^^^^^^^^^^^^^^^^^ help: remove this call error: avoid using `collect()` when not needed - --> tests/ui/needless_collect.rs:93:37 + --> tests/ui/needless_collect.rs:97:37 | LL | baz((0..10), (), ('a'..='z').collect::>()) | ^^^^^^^^^^^^^^^^^^^^ help: remove this call -error: aborting due to 19 previous errors +error: aborting due to 20 previous errors