Skip to content

Commit 1e5e541

Browse files
nahuakangY-Nak
authored andcommitted
Refactor check_for_single_element_loop to its own module
1 parent 71026ca commit 1e5e541

File tree

2 files changed

+46
-39
lines changed

2 files changed

+46
-39
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use super::get_span_of_entire_for_loop;
2+
use crate::utils::{indent_of, single_segment_path, snippet, span_lint_and_sugg};
3+
use if_chain::if_chain;
4+
use rustc_errors::Applicability;
5+
use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind};
6+
use rustc_lint::LateContext;
7+
8+
pub(super) fn check_for_single_element_loop<'tcx>(
9+
cx: &LateContext<'tcx>,
10+
pat: &'tcx Pat<'_>,
11+
arg: &'tcx Expr<'_>,
12+
body: &'tcx Expr<'_>,
13+
expr: &'tcx Expr<'_>,
14+
) {
15+
if_chain! {
16+
if let ExprKind::AddrOf(BorrowKind::Ref, _, ref arg_expr) = arg.kind;
17+
if let PatKind::Binding(.., target, _) = pat.kind;
18+
if let ExprKind::Array([arg_expression]) = arg_expr.kind;
19+
if let ExprKind::Path(ref list_item) = arg_expression.kind;
20+
if let Some(list_item_name) = single_segment_path(list_item).map(|ps| ps.ident.name);
21+
if let ExprKind::Block(ref block, _) = body.kind;
22+
if !block.stmts.is_empty();
23+
24+
then {
25+
let for_span = get_span_of_entire_for_loop(expr);
26+
let mut block_str = snippet(cx, block.span, "..").into_owned();
27+
block_str.remove(0);
28+
block_str.pop();
29+
30+
31+
span_lint_and_sugg(
32+
cx,
33+
super::SINGLE_ELEMENT_LOOP,
34+
for_span,
35+
"for loop over a single element",
36+
"try",
37+
format!("{{\n{}let {} = &{};{}}}", " ".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0)), target.name, list_item_name, block_str),
38+
Applicability::MachineApplicable
39+
)
40+
}
41+
}
42+
}

clippy_lints/src/loops/mod.rs

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@ mod for_loop_explicit_counter;
33
mod for_loop_over_map_kv;
44
mod for_loop_range;
55
mod for_mut_range_bound;
6+
mod for_single_element_loop;
67
mod manual_flatten;
78
mod utils;
89

910
use crate::consts::constant;
1011
use crate::utils::sugg::Sugg;
1112
use crate::utils::usage::mutated_variables;
1213
use crate::utils::{
13-
get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, indent_of, is_in_panic_handler,
14+
get_enclosing_block, get_parent_expr, get_trait_def_id, higher, implements_trait, is_in_panic_handler,
1415
is_integer_const, is_no_std_crate, is_refutable, is_type_diagnostic_item, last_path_segment, match_trait_method,
15-
match_type, path_to_local, path_to_local_id, paths, single_segment_path, snippet, snippet_with_applicability,
16+
match_type, path_to_local, path_to_local_id, paths, snippet, snippet_with_applicability,
1617
snippet_with_macro_callsite, span_lint, span_lint_and_help, span_lint_and_sugg, span_lint_and_then, sugg,
1718
};
1819
use if_chain::if_chain;
@@ -863,7 +864,7 @@ fn check_for_loop<'tcx>(
863864
for_loop_arg::check_for_loop_arg(cx, pat, arg, expr);
864865
for_loop_over_map_kv::check_for_loop_over_map_kv(cx, pat, arg, body, expr);
865866
for_mut_range_bound::check_for_mut_range_bound(cx, arg, body);
866-
check_for_single_element_loop(cx, pat, arg, body, expr);
867+
for_single_element_loop::check_for_single_element_loop(cx, pat, arg, body, expr);
867868
detect_same_item_push(cx, pat, arg, body, expr);
868869
manual_flatten::check_manual_flatten(cx, pat, arg, body, span);
869870
}
@@ -1464,42 +1465,6 @@ fn detect_same_item_push<'tcx>(
14641465
}
14651466
}
14661467

1467-
fn check_for_single_element_loop<'tcx>(
1468-
cx: &LateContext<'tcx>,
1469-
pat: &'tcx Pat<'_>,
1470-
arg: &'tcx Expr<'_>,
1471-
body: &'tcx Expr<'_>,
1472-
expr: &'tcx Expr<'_>,
1473-
) {
1474-
if_chain! {
1475-
if let ExprKind::AddrOf(BorrowKind::Ref, _, ref arg_expr) = arg.kind;
1476-
if let PatKind::Binding(.., target, _) = pat.kind;
1477-
if let ExprKind::Array([arg_expression]) = arg_expr.kind;
1478-
if let ExprKind::Path(ref list_item) = arg_expression.kind;
1479-
if let Some(list_item_name) = single_segment_path(list_item).map(|ps| ps.ident.name);
1480-
if let ExprKind::Block(ref block, _) = body.kind;
1481-
if !block.stmts.is_empty();
1482-
1483-
then {
1484-
let for_span = get_span_of_entire_for_loop(expr);
1485-
let mut block_str = snippet(cx, block.span, "..").into_owned();
1486-
block_str.remove(0);
1487-
block_str.pop();
1488-
1489-
1490-
span_lint_and_sugg(
1491-
cx,
1492-
SINGLE_ELEMENT_LOOP,
1493-
for_span,
1494-
"for loop over a single element",
1495-
"try",
1496-
format!("{{\n{}let {} = &{};{}}}", " ".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0)), target.name, list_item_name, block_str),
1497-
Applicability::MachineApplicable
1498-
)
1499-
}
1500-
}
1501-
}
1502-
15031468
fn is_used_inside<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, container: &'tcx Expr<'_>) -> bool {
15041469
let def_id = match path_to_local(expr) {
15051470
Some(id) => id,

0 commit comments

Comments
 (0)