]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
Update upstream source from tag 'upstream/1.52.1+dfsg1'
[rustc.git] / src / tools / clippy / clippy_lints / src / loops / single_element_loop.rs
CommitLineData
f20569fa
XL
1use super::{get_span_of_entire_for_loop, SINGLE_ELEMENT_LOOP};
2use crate::utils::{indent_of, single_segment_path, snippet, span_lint_and_sugg};
3use if_chain::if_chain;
4use rustc_errors::Applicability;
5use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind};
6use rustc_lint::LateContext;
7
8pub(super) fn check<'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 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}