}
// check for never_loop
- match expr.node {
- ExprKind::While(_, ref block, _) | ExprKind::Loop(ref block, _, _) => {
- match never_loop_block(block, expr.hir_id) {
- NeverLoopResult::AlwaysBreak => {
- span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops")
- },
- NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Otherwise => (),
- }
- },
- _ => (),
- }
+ if let ExprKind::Loop(ref block, _, _) = expr.node {
+ match never_loop_block(block, expr.hir_id) {
+ NeverLoopResult::AlwaysBreak => {
+ span_lint(cx, NEVER_LOOP, expr.span, "this loop never actually loops")
+ },
+ NeverLoopResult::MayContinueMainLoop | NeverLoopResult::Otherwise => (),
+ }
+ };
// check for `loop { if let {} else break }` that could be `while let`
// (also matches an explicit "match" instead of "if let")
}
}
- // check for while loops which conditions never change
- if let ExprKind::While(ref cond, _, _) = expr.node {
- check_infinite_loop(cx, cond, expr);
+ if_chain! {
+ if let ExprKind::Loop(block, _, LoopSource::While) = &expr.node;
+ if let Block { expr: Some(expr), .. } = &**block;
+ if let ExprKind::Match(cond, arms, MatchSource::WhileDesugar) = &expr.node;
+ if let ExprKind::DropTemps(cond) = &cond.node;
+ if let [arm, ..] = &arms[..];
+ if let Arm { body, .. } = arm;
+ then {
+ check_infinite_loop(cx, cond, body);
+ }
}
check_needless_collect(expr, cx);
// Break can come from the inner loop so remove them.
absorb_break(&never_loop_block(b, main_loop_id))
},
- ExprKind::While(ref e, ref b, _) => {
- let e = never_loop_expr(e, main_loop_id);
- let result = never_loop_block(b, main_loop_id);
- // Break can come from the inner loop so remove them.
- combine_seq(e, absorb_break(&result))
- },
ExprKind::Match(ref e, ref arms, _) => {
let e = never_loop_expr(e, main_loop_id);
if arms.is_empty() {
fn is_loop(expr: &Expr) -> bool {
match expr.node {
- ExprKind::Loop(..) | ExprKind::While(..) => true,
+ ExprKind::Loop(..) => true,
_ => false,
}
}
return false;
}
match cx.tcx.hir().find(parent) {
- Some(Node::Expr(expr)) => match expr.node {
- ExprKind::Loop(..) | ExprKind::While(..) => {
+ Some(Node::Expr(expr)) => {
+ if let ExprKind::Loop(..) = expr.node {
return true;
- },
- _ => (),
+ };
},
Some(Node::Block(block)) => {
let mut block_visitor = LoopNestVisitor {
check_expr(cx, e, bindings)
}
},
- ExprKind::While(ref cond, ref block, _) => {
- check_expr(cx, cond, bindings);
- check_block(cx, block, bindings);
- },
ExprKind::Match(ref init, ref arms, _) => {
check_expr(cx, init, bindings);
let len = bindings.len();
self.labels.remove(&label.ident.as_str());
}
},
- hir::ExprKind::Loop(_, Some(label), _) | hir::ExprKind::While(_, _, Some(label)) => {
+ hir::ExprKind::Loop(_, Some(label), _) => {
self.labels.insert(label.ident.as_str(), expr.span);
},
_ => (),
self.current = cast_pat;
self.visit_expr(expr);
},
- ExprKind::While(ref cond, ref body, _) => {
- let cond_pat = self.next("cond");
- let body_pat = self.next("body");
- let label_pat = self.next("label");
- println!(
- "While(ref {}, ref {}, ref {}) = {};",
- cond_pat, body_pat, label_pat, current
- );
- self.current = cond_pat;
- self.visit_expr(cond);
- self.current = body_pat;
- self.visit_block(body);
- },
ExprKind::Loop(ref body, _, desugaring) => {
let body_pat = self.next("body");
let des = loop_desugaring_name(desugaring);
match des {
hir::MatchSource::ForLoopDesugar => "MatchSource::ForLoopDesugar".to_string(),
hir::MatchSource::TryDesugar => "MatchSource::TryDesugar".to_string(),
+ hir::MatchSource::WhileDesugar => "MatchSource::WhileDesugar".to_string(),
hir::MatchSource::WhileLetDesugar => "MatchSource::WhileLetDesugar".to_string(),
hir::MatchSource::Normal => "MatchSource::Normal".to_string(),
hir::MatchSource::IfLetDesugar { contains_else_clause } => format!(
match des {
hir::LoopSource::ForLoop => "LoopSource::ForLoop",
hir::LoopSource::Loop => "LoopSource::Loop",
+ hir::LoopSource::While => "LoopSource::WhileDesugar",
hir::LoopSource::WhileLet => "LoopSource::WhileLet",
}
}
(&ExprKind::Tup(ref l_tup), &ExprKind::Tup(ref r_tup)) => self.eq_exprs(l_tup, r_tup),
(&ExprKind::Unary(l_op, ref le), &ExprKind::Unary(r_op, ref re)) => l_op == r_op && self.eq_expr(le, re),
(&ExprKind::Array(ref l), &ExprKind::Array(ref r)) => self.eq_exprs(l, r),
- (&ExprKind::While(ref lc, ref lb, ref ll), &ExprKind::While(ref rc, ref rb, ref rl)) => {
- self.eq_expr(lc, rc)
- && self.eq_block(lb, rb)
- && both(ll, rl, |l, r| l.ident.as_str() == r.ident.as_str())
- },
(&ExprKind::DropTemps(ref le), &ExprKind::DropTemps(ref re)) => self.eq_expr(le, re),
_ => false,
}
lop.hash(&mut self.s);
self.hash_expr(le);
},
- ExprKind::While(ref cond, ref b, l) => {
- self.hash_expr(cond);
- self.hash_block(b);
- if let Some(l) = l {
- self.hash_name(l.ident.name);
- }
- },
}
}
print_expr(cx, e, indent + 1);
println!("{}target type: {:?}", ind, target);
},
- hir::ExprKind::While(ref cond, _, _) => {
- println!("{}While", ind);
- println!("{}condition:", ind);
- print_expr(cx, cond, indent + 1);
- },
hir::ExprKind::Loop(..) => {
println!("{}Loop", ind);
},
| hir::ExprKind::Ret(..)
| hir::ExprKind::Struct(..)
| hir::ExprKind::Tup(..)
- | hir::ExprKind::While(..)
| hir::ExprKind::DropTemps(_)
| hir::ExprKind::Err => Sugg::NonParen(snippet),
hir::ExprKind::Assign(..) => Sugg::BinOp(AssocOp::Assign, snippet),