Skip to content

Commit ed32876

Browse files
committed
Auto merge of #3757 - mikerite:fix-2542, r=oli-obk
Fix `needless_range_loop` bad suggestion Detect if the index variable is used inside a closure. Fixes #2542
2 parents 2066368 + 217965e commit ed32876

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

clippy_lints/src/loops.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1830,17 +1830,29 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
18301830
if let ExprKind::Path(ref qpath) = expr.node;
18311831
if let QPath::Resolved(None, ref path) = *qpath;
18321832
if path.segments.len() == 1;
1833-
if let Def::Local(local_id) = self.cx.tables.qpath_def(qpath, expr.hir_id);
18341833
then {
1835-
if local_id == self.var {
1836-
// we are not indexing anything, record that
1837-
self.nonindex = true;
1838-
} else {
1839-
// not the correct variable, but still a variable
1840-
self.referenced.insert(path.segments[0].ident.name);
1834+
match self.cx.tables.qpath_def(qpath, expr.hir_id) {
1835+
Def::Upvar(local_id, ..) => {
1836+
if local_id == self.var {
1837+
// we are not indexing anything, record that
1838+
self.nonindex = true;
1839+
}
1840+
}
1841+
Def::Local(local_id) =>
1842+
{
1843+
1844+
if local_id == self.var {
1845+
self.nonindex = true;
1846+
} else {
1847+
// not the correct variable, but still a variable
1848+
self.referenced.insert(path.segments[0].ident.name);
1849+
}
1850+
}
1851+
_ => {}
18411852
}
18421853
}
18431854
}
1855+
18441856
let old = self.prefer_mutable;
18451857
match expr.node {
18461858
ExprKind::AssignOp(_, ref lhs, ref rhs) | ExprKind::Assign(ref lhs, ref rhs) => {
@@ -1880,6 +1892,10 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
18801892
self.visit_expr(expr);
18811893
}
18821894
},
1895+
ExprKind::Closure(_, _, body_id, ..) => {
1896+
let body = self.cx.tcx.hir().body(body_id);
1897+
self.visit_expr(&body.value);
1898+
},
18831899
_ => walk_expr(self, expr),
18841900
}
18851901
self.prefer_mutable = old;

tests/ui/needless_range_loop.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,9 @@ fn main() {
8080
for i in 1..3 {
8181
println!("{}", arr[i]);
8282
}
83+
84+
// #2542
85+
for i in 0..vec.len() {
86+
vec[i] = Some(1).unwrap_or_else(|| panic!("error on {}", i));
87+
}
8388
}

tests/ui/needless_range_loop.stderr

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,5 +80,15 @@ help: consider using an iterator
8080
LL | for <item> in arr.iter().skip(1) {
8181
| ^^^^^^ ^^^^^^^^^^^^^^^^^^
8282

83-
error: aborting due to 8 previous errors
83+
error: the loop variable `i` is used to index `vec`
84+
--> $DIR/needless_range_loop.rs:85:14
85+
|
86+
LL | for i in 0..vec.len() {
87+
| ^^^^^^^^^^^^
88+
help: consider using an iterator
89+
|
90+
LL | for (i, <item>) in vec.iter_mut().enumerate() {
91+
| ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^
92+
93+
error: aborting due to 9 previous errors
8494

0 commit comments

Comments
 (0)