]> git.proxmox.com Git - rustc.git/blame - src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
New upstream version 1.58.1+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / loops / single_element_loop.rs
CommitLineData
3c0e092e 1use super::SINGLE_ELEMENT_LOOP;
cdc7bbd5
XL
2use clippy_utils::diagnostics::span_lint_and_sugg;
3use clippy_utils::single_segment_path;
4use clippy_utils::source::{indent_of, snippet};
f20569fa
XL
5use if_chain::if_chain;
6use rustc_errors::Applicability;
7use rustc_hir::{BorrowKind, Expr, ExprKind, Pat, PatKind};
8use rustc_lint::LateContext;
9
10pub(super) fn check<'tcx>(
11 cx: &LateContext<'tcx>,
12 pat: &'tcx Pat<'_>,
13 arg: &'tcx Expr<'_>,
14 body: &'tcx Expr<'_>,
15 expr: &'tcx Expr<'_>,
16) {
cdc7bbd5
XL
17 let arg_expr = match arg.kind {
18 ExprKind::AddrOf(BorrowKind::Ref, _, ref_arg) => ref_arg,
19 ExprKind::MethodCall(method, _, args, _) if args.len() == 1 && method.ident.name == rustc_span::sym::iter => {
20 &args[0]
21 },
22 _ => return,
23 };
f20569fa 24 if_chain! {
f20569fa
XL
25 if let PatKind::Binding(.., target, _) = pat.kind;
26 if let ExprKind::Array([arg_expression]) = arg_expr.kind;
27 if let ExprKind::Path(ref list_item) = arg_expression.kind;
28 if let Some(list_item_name) = single_segment_path(list_item).map(|ps| ps.ident.name);
cdc7bbd5 29 if let ExprKind::Block(block, _) = body.kind;
f20569fa
XL
30 if !block.stmts.is_empty();
31
32 then {
f20569fa
XL
33 let mut block_str = snippet(cx, block.span, "..").into_owned();
34 block_str.remove(0);
35 block_str.pop();
36
37
38 span_lint_and_sugg(
39 cx,
40 SINGLE_ELEMENT_LOOP,
3c0e092e 41 expr.span,
f20569fa
XL
42 "for loop over a single element",
43 "try",
44 format!("{{\n{}let {} = &{};{}}}", " ".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0)), target.name, list_item_name, block_str),
45 Applicability::MachineApplicable
46 )
47 }
48 }
49}