]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use super::{get_span_of_entire_for_loop, SINGLE_ELEMENT_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<'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 | } |