Skip to content

Commit 70c46de

Browse files
committed
Auto merge of #5877 - ebroto:5872_loops_ice, r=Manishearth
Fix ICE in `loops` module changelog: Fix ICE related to `needless_collect` when a call to `iter()` was not present. I went for restoring the old suggestion of `next().is_some()` over `get(0).is_some()` given that `iter()` is not necessarily present (could be e.g. `into_iter()` or `iter_mut()`) and that the old suggestion could change semantics, e.g. a call to `filter()` could be present between `iter()` and the collect part. Fixes #5872
2 parents 3899d60 + 888657e commit 70c46de

File tree

6 files changed

+30
-15
lines changed

6 files changed

+30
-15
lines changed

clippy_lints/src/loops.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -2374,7 +2374,7 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
23742374
match_type(cx, ty, &paths::BTREEMAP) ||
23752375
is_type_diagnostic_item(cx, ty, sym!(hashmap_type)) {
23762376
if method.ident.name == sym!(len) {
2377-
let span = shorten_span(expr, sym!(collect));
2377+
let span = shorten_needless_collect_span(expr);
23782378
span_lint_and_sugg(
23792379
cx,
23802380
NEEDLESS_COLLECT,
@@ -2386,20 +2386,20 @@ fn check_needless_collect_direct_usage<'tcx>(expr: &'tcx Expr<'_>, cx: &LateCont
23862386
);
23872387
}
23882388
if method.ident.name == sym!(is_empty) {
2389-
let span = shorten_span(expr, sym!(iter));
2389+
let span = shorten_needless_collect_span(expr);
23902390
span_lint_and_sugg(
23912391
cx,
23922392
NEEDLESS_COLLECT,
23932393
span,
23942394
NEEDLESS_COLLECT_MSG,
23952395
"replace with",
2396-
"get(0).is_none()".to_string(),
2396+
"next().is_none()".to_string(),
23972397
Applicability::MachineApplicable,
23982398
);
23992399
}
24002400
if method.ident.name == sym!(contains) {
24012401
let contains_arg = snippet(cx, args[1].span, "??");
2402-
let span = shorten_span(expr, sym!(collect));
2402+
let span = shorten_needless_collect_span(expr);
24032403
span_lint_and_then(
24042404
cx,
24052405
NEEDLESS_COLLECT,
@@ -2579,13 +2579,13 @@ fn detect_iter_and_into_iters<'tcx>(block: &'tcx Block<'tcx>, identifier: Ident)
25792579
}
25802580
}
25812581

2582-
fn shorten_span(expr: &Expr<'_>, target_fn_name: Symbol) -> Span {
2583-
let mut current_expr = expr;
2584-
while let ExprKind::MethodCall(ref path, ref span, ref args, _) = current_expr.kind {
2585-
if path.ident.name == target_fn_name {
2582+
fn shorten_needless_collect_span(expr: &Expr<'_>) -> Span {
2583+
if_chain! {
2584+
if let ExprKind::MethodCall(.., args, _) = &expr.kind;
2585+
if let ExprKind::MethodCall(_, span, ..) = &args[0].kind;
2586+
then {
25862587
return expr.span.with_lo(span.lo());
25872588
}
2588-
current_expr = &args[0];
25892589
}
2590-
unreachable!()
2590+
unreachable!();
25912591
}

tests/ui/crashes/ice-5872.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![warn(clippy::needless_collect)]
2+
3+
fn main() {
4+
let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();
5+
}

tests/ui/crashes/ice-5872.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: avoid using `collect()` when not needed
2+
--> $DIR/ice-5872.rs:4:39
3+
|
4+
LL | let _ = vec![1, 2, 3].into_iter().collect::<Vec<_>>().is_empty();
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
6+
|
7+
= note: `-D clippy::needless-collect` implied by `-D warnings`
8+
9+
error: aborting due to previous error
10+

tests/ui/needless_collect.fixed

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
use std::collections::{BTreeSet, HashMap, HashSet};
66

77
#[warn(clippy::needless_collect)]
8-
#[allow(unused_variables, clippy::iter_cloned_collect)]
8+
#[allow(unused_variables, clippy::iter_cloned_collect, clippy::iter_next_slice)]
99
fn main() {
1010
let sample = [1; 5];
1111
let len = sample.iter().count();
12-
if sample.get(0).is_none() {
12+
if sample.iter().next().is_none() {
1313
// Empty
1414
}
1515
sample.iter().cloned().any(|x| x == 1);

tests/ui/needless_collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use std::collections::{BTreeSet, HashMap, HashSet};
66

77
#[warn(clippy::needless_collect)]
8-
#[allow(unused_variables, clippy::iter_cloned_collect)]
8+
#[allow(unused_variables, clippy::iter_cloned_collect, clippy::iter_next_slice)]
99
fn main() {
1010
let sample = [1; 5];
1111
let len = sample.iter().collect::<Vec<_>>().len();

tests/ui/needless_collect.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ LL | let len = sample.iter().collect::<Vec<_>>().len();
77
= note: `-D clippy::needless-collect` implied by `-D warnings`
88

99
error: avoid using `collect()` when not needed
10-
--> $DIR/needless_collect.rs:12:15
10+
--> $DIR/needless_collect.rs:12:22
1111
|
1212
LL | if sample.iter().collect::<Vec<_>>().is_empty() {
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `get(0).is_none()`
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `next().is_none()`
1414

1515
error: avoid using `collect()` when not needed
1616
--> $DIR/needless_collect.rs:15:28

0 commit comments

Comments
 (0)