Skip to content

Commit

Permalink
Rollup merge of rust-lang#81236 - estebank:everybody-loop-now, r=oli-obk
Browse files Browse the repository at this point in the history
Gracefully handle loop labels missing leading `'` in different positions

Fix rust-lang#81192.

* Account for labels when suggesting `loop` instead of `while true`
* Suggest `'a` when given `a` only when appropriate
* Add loop head span to hir
* Tweak error for invalid `break expr`
* Add more misspelled label tests
* Avoid emitting redundant "unused label" lint
* Parse loop labels missing a leading `'`

Each commit can be reviewed in isolation.
  • Loading branch information
m-ou-se authored Jan 22, 2021
2 parents a1b89f0 + 3a5ede6 commit e9b2cf4
Show file tree
Hide file tree
Showing 6 changed files with 11 additions and 11 deletions.
8 changes: 4 additions & 4 deletions clippy_lints/src/loops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
}

// check for never_loop
if let ExprKind::Loop(ref block, _, _) = expr.kind {
if let ExprKind::Loop(ref block, _, _, _) = expr.kind {
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 => (),
Expand All @@ -543,7 +543,7 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
// check for `loop { if let {} else break }` that could be `while let`
// (also matches an explicit "match" instead of "if let")
// (even if the "match" or "if let" is used for declaration)
if let ExprKind::Loop(ref block, _, LoopSource::Loop) = expr.kind {
if let ExprKind::Loop(ref block, _, LoopSource::Loop, _) = expr.kind {
// also check for empty `loop {}` statements, skipping those in #[panic_handler]
if block.stmts.is_empty() && block.expr.is_none() && !is_in_panic_handler(cx, expr) {
let msg = "empty `loop {}` wastes CPU cycles";
Expand Down Expand Up @@ -738,7 +738,7 @@ fn never_loop_expr(expr: &Expr<'_>, main_loop_id: HirId) -> NeverLoopResult {
| ExprKind::Assign(ref e1, ref e2, _)
| ExprKind::AssignOp(_, ref e1, ref e2)
| ExprKind::Index(ref e1, ref e2) => never_loop_expr_all(&mut [&**e1, &**e2].iter().cloned(), main_loop_id),
ExprKind::Loop(ref b, _, _) => {
ExprKind::Loop(ref b, _, _, _) => {
// Break can come from the inner loop so remove them.
absorb_break(&never_loop_block(b, main_loop_id))
},
Expand Down Expand Up @@ -1314,7 +1314,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
match &expr.kind {
// Non-determinism may occur ... don't give a lint
ExprKind::Loop(_, _, _) | ExprKind::Match(_, _, _) => self.should_lint = false,
ExprKind::Loop(..) | ExprKind::Match(..) => self.should_lint = false,
ExprKind::Block(block, _) => self.visit_block(block),
_ => {},
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/needless_continue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ where
{
if let ast::ExprKind::While(_, loop_block, label)
| ast::ExprKind::ForLoop(_, _, loop_block, label)
| ast::ExprKind::Loop(loop_block, label) = &expr.kind
| ast::ExprKind::Loop(loop_block, label, ..) = &expr.kind
{
func(loop_block, label.as_ref());
}
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut
| ExprKind::Field(ref e, _)
| ExprKind::AddrOf(_, _, ref e)
| ExprKind::Box(ref e) => check_expr(cx, e, bindings),
ExprKind::Block(ref block, _) | ExprKind::Loop(ref block, _, _) => check_block(cx, block, bindings),
ExprKind::Block(ref block, _) | ExprKind::Loop(ref block, ..) => check_block(cx, block, bindings),
// ExprKind::Call
// ExprKind::MethodCall
ExprKind::Array(v) | ExprKind::Tup(v) => {
Expand Down
2 changes: 1 addition & 1 deletion clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ impl<'tcx> Visitor<'tcx> for PrintVisitor {
self.current = cast_pat;
self.visit_expr(expr);
},
ExprKind::Loop(ref body, _, desugaring) => {
ExprKind::Loop(ref body, _, desugaring, _) => {
let body_pat = self.next("body");
let des = loop_desugaring_name(desugaring);
let label_pat = self.next("label");
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/utils/higher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ pub fn for_loop<'tcx>(
if let hir::ExprKind::Match(ref iterexpr, ref arms, hir::MatchSource::ForLoopDesugar) = expr.kind;
if let hir::ExprKind::Call(_, ref iterargs) = iterexpr.kind;
if iterargs.len() == 1 && arms.len() == 1 && arms[0].guard.is_none();
if let hir::ExprKind::Loop(ref block, _, _) = arms[0].body.kind;
if let hir::ExprKind::Loop(ref block, ..) = arms[0].body.kind;
if block.expr.is_none();
if let [ _, _, ref let_stmt, ref body ] = *block.stmts;
if let hir::StmtKind::Local(ref local) = let_stmt.kind;
Expand All @@ -158,7 +158,7 @@ pub fn for_loop<'tcx>(
/// `while cond { body }` becomes `(cond, body)`.
pub fn while_loop<'tcx>(expr: &'tcx hir::Expr<'tcx>) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::Expr<'tcx>)> {
if_chain! {
if let hir::ExprKind::Loop(block, _, hir::LoopSource::While) = &expr.kind;
if let hir::ExprKind::Loop(block, _, hir::LoopSource::While, _) = &expr.kind;
if let hir::Block { expr: Some(expr), .. } = &**block;
if let hir::ExprKind::Match(cond, arms, hir::MatchSource::WhileDesugar) = &expr.kind;
if let hir::ExprKind::DropTemps(cond) = &cond.kind;
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/utils/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ impl<'a, 'tcx> SpanlessEq<'a, 'tcx> {
self.eq_expr(lc, rc) && self.eq_expr(&**lt, &**rt) && both(le, re, |l, r| self.eq_expr(l, r))
},
(&ExprKind::Lit(ref l), &ExprKind::Lit(ref r)) => l.node == r.node,
(&ExprKind::Loop(ref lb, ref ll, ref lls), &ExprKind::Loop(ref rb, ref rl, ref rls)) => {
(&ExprKind::Loop(ref lb, ref ll, ref lls, _), &ExprKind::Loop(ref rb, ref rl, ref rls, _)) => {
lls == rls && self.eq_block(lb, rb) && both(ll, rl, |l, r| l.ident.name == r.ident.name)
},
(&ExprKind::Match(ref le, ref la, ref ls), &ExprKind::Match(ref re, ref ra, ref rs)) => {
Expand Down Expand Up @@ -560,7 +560,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
ExprKind::Lit(ref l) => {
l.node.hash(&mut self.s);
},
ExprKind::Loop(ref b, ref i, _) => {
ExprKind::Loop(ref b, ref i, ..) => {
self.hash_block(b);
if let Some(i) = *i {
self.hash_name(i.ident.name);
Expand Down

0 comments on commit e9b2cf4

Please sign in to comment.