Skip to content

Commit 5ad79c2

Browse files
author
Michael Wright
committed
Fix breakage due to rust-lang/rust#60225
1 parent 910d538 commit 5ad79c2

File tree

6 files changed

+78
-74
lines changed

6 files changed

+78
-74
lines changed

clippy_lints/src/loops.rs

+43-50
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,8 @@ fn never_loop_expr(expr: &Expr, main_loop_id: HirId) -> NeverLoopResult {
676676
| ExprKind::Field(ref e, _)
677677
| ExprKind::AddrOf(_, ref e)
678678
| ExprKind::Struct(_, _, Some(ref e))
679-
| ExprKind::Repeat(ref e, _) => never_loop_expr(e, main_loop_id),
679+
| ExprKind::Repeat(ref e, _)
680+
| ExprKind::Use(ref e) => never_loop_expr(e, main_loop_id),
680681
ExprKind::Array(ref es) | ExprKind::MethodCall(_, _, ref es) | ExprKind::Tup(ref es) => {
681682
never_loop_expr_all(&mut es.iter(), main_loop_id)
682683
},
@@ -1458,54 +1459,46 @@ fn check_for_loop_explicit_counter<'a, 'tcx>(
14581459

14591460
// For each candidate, check the parent block to see if
14601461
// it's initialized to zero at the start of the loop.
1461-
let map = &cx.tcx.hir();
1462-
let expr_node_id = expr.hir_id;
1463-
let parent_scope = map
1464-
.get_enclosing_scope(expr_node_id)
1465-
.and_then(|id| map.get_enclosing_scope(id));
1466-
if let Some(parent_id) = parent_scope {
1467-
if let Node::Block(block) = map.get_by_hir_id(parent_id) {
1468-
for (id, _) in visitor.states.iter().filter(|&(_, v)| *v == VarState::IncrOnce) {
1469-
let mut visitor2 = InitializeVisitor {
1470-
cx,
1471-
end_expr: expr,
1472-
var_id: *id,
1473-
state: VarState::IncrOnce,
1474-
name: None,
1475-
depth: 0,
1476-
past_loop: false,
1477-
};
1478-
walk_block(&mut visitor2, block);
1479-
1480-
if visitor2.state == VarState::Warn {
1481-
if let Some(name) = visitor2.name {
1482-
let mut applicability = Applicability::MachineApplicable;
1483-
span_lint_and_sugg(
1484-
cx,
1485-
EXPLICIT_COUNTER_LOOP,
1486-
expr.span,
1487-
&format!("the variable `{}` is used as a loop counter.", name),
1488-
"consider using",
1489-
format!(
1490-
"for ({}, {}) in {}.enumerate()",
1491-
name,
1492-
snippet_with_applicability(cx, pat.span, "item", &mut applicability),
1493-
if higher::range(cx, arg).is_some() {
1494-
format!(
1495-
"({})",
1496-
snippet_with_applicability(cx, arg.span, "_", &mut applicability)
1497-
)
1498-
} else {
1499-
format!(
1500-
"{}",
1501-
sugg::Sugg::hir_with_applicability(cx, arg, "_", &mut applicability)
1502-
.maybe_par()
1503-
)
1504-
}
1505-
),
1506-
applicability,
1507-
);
1508-
}
1462+
if let Some(block) = get_enclosing_block(&cx, expr.hir_id) {
1463+
for (id, _) in visitor.states.iter().filter(|&(_, v)| *v == VarState::IncrOnce) {
1464+
let mut visitor2 = InitializeVisitor {
1465+
cx,
1466+
end_expr: expr,
1467+
var_id: *id,
1468+
state: VarState::IncrOnce,
1469+
name: None,
1470+
depth: 0,
1471+
past_loop: false,
1472+
};
1473+
walk_block(&mut visitor2, block);
1474+
1475+
if visitor2.state == VarState::Warn {
1476+
if let Some(name) = visitor2.name {
1477+
let mut applicability = Applicability::MachineApplicable;
1478+
span_lint_and_sugg(
1479+
cx,
1480+
EXPLICIT_COUNTER_LOOP,
1481+
expr.span,
1482+
&format!("the variable `{}` is used as a loop counter.", name),
1483+
"consider using",
1484+
format!(
1485+
"for ({}, {}) in {}.enumerate()",
1486+
name,
1487+
snippet_with_applicability(cx, pat.span, "item", &mut applicability),
1488+
if higher::range(cx, arg).is_some() {
1489+
format!(
1490+
"({})",
1491+
snippet_with_applicability(cx, arg.span, "_", &mut applicability)
1492+
)
1493+
} else {
1494+
format!(
1495+
"{}",
1496+
sugg::Sugg::hir_with_applicability(cx, arg, "_", &mut applicability).maybe_par()
1497+
)
1498+
}
1499+
),
1500+
applicability,
1501+
);
15091502
}
15101503
}
15111504
}
@@ -2042,7 +2035,7 @@ fn is_simple_break_expr(expr: &Expr) -> bool {
20422035
// To trigger the EXPLICIT_COUNTER_LOOP lint, a variable must be
20432036
// incremented exactly once in the loop body, and initialized to zero
20442037
// at the start of the loop.
2045-
#[derive(PartialEq)]
2038+
#[derive(Debug, PartialEq)]
20462039
enum VarState {
20472040
Initial, // Not examined yet
20482041
IncrOnce, // Incremented exactly once, may be a loop counter

clippy_lints/src/utils/author.rs

+6
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
495495
ExprKind::Err => {
496496
println!("Err = {}", current);
497497
},
498+
ExprKind::Use(ref expr) => {
499+
let expr_pat = self.next("expr");
500+
println!("Use(ref {}) = {};", expr_pat, current);
501+
self.current = expr_pat;
502+
self.visit_expr(expr);
503+
},
498504
}
499505
}
500506

clippy_lints/src/utils/hir_utils.rs

+6
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ impl<'a, 'tcx: 'a> SpanlessEq<'a, 'tcx> {
156156
&& self.eq_block(lb, rb)
157157
&& both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str())
158158
},
159+
(&ExprKind::Use(ref le), &ExprKind::Use(ref re)) => self.eq_expr(le, re),
159160
_ => false,
160161
}
161162
}
@@ -606,6 +607,11 @@ impl<'a, 'tcx: 'a> SpanlessHash<'a, 'tcx> {
606607
}
607608
},
608609
ExprKind::Err => {},
610+
ExprKind::Use(ref e) => {
611+
let c: fn(_) -> _ = ExprKind::Use;
612+
c.hash(&mut self.s);
613+
self.hash_expr(e);
614+
},
609615
}
610616
}
611617

clippy_lints/src/utils/inspector.rs

+4
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,10 @@ fn print_expr(cx: &LateContext<'_, '_>, expr: &hir::Expr, indent: usize) {
330330
hir::ExprKind::Err => {
331331
println!("{}Err", ind);
332332
},
333+
hir::ExprKind::Use(ref e) => {
334+
println!("{}Use", ind);
335+
print_expr(cx, e, indent + 1);
336+
},
333337
}
334338
}
335339

clippy_lints/src/utils/sugg.rs

+1
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ impl<'a> Sugg<'a> {
115115
| hir::ExprKind::Struct(..)
116116
| hir::ExprKind::Tup(..)
117117
| hir::ExprKind::While(..)
118+
| hir::ExprKind::Use(_)
118119
| hir::ExprKind::Err => Sugg::NonParen(snippet),
119120
hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),
120121
hir::ExprKind::AssignOp(op, ..) => Sugg::BinOp(hirbinop2assignop(op), snippet),

tests/ui/author/for_loop.stdout

+18-24
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
if_chain! {
2-
if let ExprKind::Block(ref block) = expr.node;
3-
if let StmtKind::Local(ref local) = block.node;
4-
if let Some(ref init) = local.init;
5-
if let ExprKind::Match(ref expr, ref arms, MatchSource::ForLoopDesugar) = init.node;
6-
if let ExprKind::Call(ref func, ref args) = expr.node;
2+
if let ExprKind::Use(ref expr) = expr.node;
3+
if let ExprKind::Match(ref expr1, ref arms, MatchSource::ForLoopDesugar) = expr.node;
4+
if let ExprKind::Call(ref func, ref args) = expr1.node;
75
if let ExprKind::Path(ref path) = func.node;
86
if match_qpath(path, &["{{root}}", "std", "iter", "IntoIterator", "into_iter"]);
97
if args.len() == 1;
@@ -13,12 +11,12 @@ if_chain! {
1311
// unimplemented: field checks
1412
if arms.len() == 1;
1513
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.node;
16-
if let StmtKind::Local(ref local1) = body.node;
17-
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local1.pat.node;
14+
if let StmtKind::Local(ref local) = body.node;
15+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.node;
1816
if name.node.as_str() == "__next";
19-
if let StmtKind::Expr(ref e, _) = local1.pat.node
20-
if let ExprKind::Match(ref expr1, ref arms1, MatchSource::ForLoopDesugar) = e.node;
21-
if let ExprKind::Call(ref func1, ref args1) = expr1.node;
17+
if let StmtKind::Expr(ref e, _) = local.pat.node
18+
if let ExprKind::Match(ref expr2, ref arms1, MatchSource::ForLoopDesugar) = e.node;
19+
if let ExprKind::Call(ref func1, ref args1) = expr2.node;
2220
if let ExprKind::Path(ref path2) = func1.node;
2321
if match_qpath(path2, &["{{root}}", "std", "iter", "Iterator", "next"]);
2422
if args1.len() == 1;
@@ -40,27 +38,23 @@ if_chain! {
4038
if arms1[1].pats.len() == 1;
4139
if let PatKind::Path(ref path7) = arms1[1].pats[0].node;
4240
if match_qpath(path7, &["{{root}}", "std", "option", "Option", "None"]);
43-
if let StmtKind::Local(ref local2) = path7.node;
44-
if let Some(ref init1) = local2.init;
45-
if let ExprKind::Path(ref path8) = init1.node;
41+
if let StmtKind::Local(ref local1) = path7.node;
42+
if let Some(ref init) = local1.init;
43+
if let ExprKind::Path(ref path8) = init.node;
4644
if match_qpath(path8, &["__next"]);
47-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local2.pat.node;
45+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.node;
4846
if name1.node.as_str() == "y";
49-
if let StmtKind::Expr(ref e1, _) = local2.pat.node
50-
if let ExprKind::Block(ref block1) = e1.node;
51-
if let StmtKind::Local(ref local3) = block1.node;
52-
if let Some(ref init2) = local3.init;
53-
if let ExprKind::Path(ref path9) = init2.node;
47+
if let StmtKind::Expr(ref e1, _) = local1.pat.node
48+
if let ExprKind::Block(ref block) = e1.node;
49+
if let StmtKind::Local(ref local2) = block.node;
50+
if let Some(ref init1) = local2.init;
51+
if let ExprKind::Path(ref path9) = init1.node;
5452
if match_qpath(path9, &["y"]);
55-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local3.pat.node;
53+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local2.pat.node;
5654
if name2.node.as_str() == "z";
5755
if arms[0].pats.len() == 1;
5856
if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pats[0].node;
5957
if name3.node.as_str() == "iter";
60-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name4, None) = local.pat.node;
61-
if name4.node.as_str() == "_result";
62-
if let ExprKind::Path(ref path10) = local.pat.node;
63-
if match_qpath(path10, &["_result"]);
6458
then {
6559
// report your lint here
6660
}

0 commit comments

Comments
 (0)