diff options
| author | Raiki Tamura <tamaron1203@gmail.com> | 2023-01-05 18:30:13 +0900 |
|---|---|---|
| committer | Raiki Tamura <tamaron1203@gmail.com> | 2023-01-05 18:30:13 +0900 |
| commit | 79ed23ff815bc39d0062ade40b2c38dd37e77373 (patch) | |
| tree | f8890068101fdaf4256e6ae937ec425d21b12b6c | |
| parent | 61ff54e5c22736bad5fc4f41d3cc36208475510c (diff) | |
| download | rust-79ed23ff815bc39d0062ade40b2c38dd37e77373.tar.gz rust-79ed23ff815bc39d0062ade40b2c38dd37e77373.zip | |
fix
| -rw-r--r-- | clippy_lints/src/loops/single_element_loop.rs | 14 | ||||
| -rw-r--r-- | tests/ui/single_element_loop.fixed | 27 | ||||
| -rw-r--r-- | tests/ui/single_element_loop.rs | 26 | ||||
| -rw-r--r-- | tests/ui/single_element_loop.stderr | 29 |
4 files changed, 95 insertions, 1 deletions
diff --git a/clippy_lints/src/loops/single_element_loop.rs b/clippy_lints/src/loops/single_element_loop.rs index f4b47808dfa..7cbc456244e 100644 --- a/clippy_lints/src/loops/single_element_loop.rs +++ b/clippy_lints/src/loops/single_element_loop.rs @@ -1,6 +1,7 @@ use super::SINGLE_ELEMENT_LOOP; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::{indent_of, snippet_with_applicability}; +use clippy_utils::visitors::for_each_expr; use if_chain::if_chain; use rustc_ast::util::parser::PREC_PREFIX; use rustc_ast::Mutability; @@ -8,6 +9,18 @@ use rustc_errors::Applicability; use rustc_hir::{is_range_literal, BorrowKind, Expr, ExprKind, Pat}; use rustc_lint::LateContext; use rustc_span::edition::Edition; +use std::ops::ControlFlow; + +fn contains_break_or_continue(expr: &Expr<'_>) -> bool { + for_each_expr(expr, |e| { + if matches!(e.kind, ExprKind::Break(..) | ExprKind::Continue(..)) { + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + }) + .is_some() +} pub(super) fn check<'tcx>( cx: &LateContext<'tcx>, @@ -67,6 +80,7 @@ pub(super) fn check<'tcx>( if_chain! { if let ExprKind::Block(block, _) = body.kind; if !block.stmts.is_empty(); + if !contains_break_or_continue(body); then { let mut applicability = Applicability::MachineApplicable; let pat_snip = snippet_with_applicability(cx, pat.span, "..", &mut applicability); diff --git a/tests/ui/single_element_loop.fixed b/tests/ui/single_element_loop.fixed index 63d31ff83f9..a0dcc0172e8 100644 --- a/tests/ui/single_element_loop.fixed +++ b/tests/ui/single_element_loop.fixed @@ -33,4 +33,31 @@ fn main() { let item = 0..5; dbg!(item); } + + // should not lint (issue #10018) + for e in [42] { + if e > 0 { + continue; + } + } + + // should not lint (issue #10018) + for e in [42] { + if e > 0 { + break; + } + } + + // should lint (issue #10018) + { + let _ = 42; + let _f = |n: u32| { + for i in 0..n { + if i > 10 { + dbg!(i); + break; + } + } + }; + } } diff --git a/tests/ui/single_element_loop.rs b/tests/ui/single_element_loop.rs index 2cda5a329d2..bc014035c98 100644 --- a/tests/ui/single_element_loop.rs +++ b/tests/ui/single_element_loop.rs @@ -27,4 +27,30 @@ fn main() { for item in [0..5].into_iter() { dbg!(item); } + + // should not lint (issue #10018) + for e in [42] { + if e > 0 { + continue; + } + } + + // should not lint (issue #10018) + for e in [42] { + if e > 0 { + break; + } + } + + // should lint (issue #10018) + for _ in [42] { + let _f = |n: u32| { + for i in 0..n { + if i > 10 { + dbg!(i); + break; + } + } + }; + } } diff --git a/tests/ui/single_element_loop.stderr b/tests/ui/single_element_loop.stderr index 0aeb8da1a2e..14437a59745 100644 --- a/tests/ui/single_element_loop.stderr +++ b/tests/ui/single_element_loop.stderr @@ -95,5 +95,32 @@ LL + dbg!(item); LL + } | -error: aborting due to 6 previous errors +error: for loop over a single element + --> $DIR/single_element_loop.rs:46:5 + | +LL | / for _ in [42] { +LL | | let _f = |n: u32| { +LL | | for i in 0..n { +LL | | if i > 10 { +... | +LL | | }; +LL | | } + | |_____^ + | +help: try + | +LL ~ { +LL + let _ = 42; +LL + let _f = |n: u32| { +LL + for i in 0..n { +LL + if i > 10 { +LL + dbg!(i); +LL + break; +LL + } +LL + } +LL + }; +LL + } + | + +error: aborting due to 7 previous errors |
