2021-10-27 14:48:06 +00:00
|
|
|
use super::SINGLE_ELEMENT_LOOP;
|
2021-03-25 18:29:11 +00:00
|
|
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
2022-01-06 15:31:38 +00:00
|
|
|
use clippy_utils::source::{indent_of, snippet_with_applicability};
|
2021-03-12 14:30:50 +00:00
|
|
|
use if_chain::if_chain;
|
|
|
|
use rustc_errors::Applicability;
|
2022-01-06 15:31:38 +00:00
|
|
|
use rustc_hir::{BorrowKind, Expr, ExprKind, Pat};
|
2021-03-12 14:30:50 +00:00
|
|
|
use rustc_lint::LateContext;
|
|
|
|
|
|
|
|
pub(super) fn check<'tcx>(
|
|
|
|
cx: &LateContext<'tcx>,
|
|
|
|
pat: &'tcx Pat<'_>,
|
|
|
|
arg: &'tcx Expr<'_>,
|
|
|
|
body: &'tcx Expr<'_>,
|
|
|
|
expr: &'tcx Expr<'_>,
|
|
|
|
) {
|
2021-04-27 14:55:11 +00:00
|
|
|
let arg_expr = match arg.kind {
|
|
|
|
ExprKind::AddrOf(BorrowKind::Ref, _, ref_arg) => ref_arg,
|
2022-01-06 15:31:38 +00:00
|
|
|
ExprKind::MethodCall(method, [arg], _) if method.ident.name == rustc_span::sym::iter => arg,
|
2021-04-27 14:55:11 +00:00
|
|
|
_ => return,
|
|
|
|
};
|
2021-03-12 14:30:50 +00:00
|
|
|
if_chain! {
|
|
|
|
if let ExprKind::Array([arg_expression]) = arg_expr.kind;
|
2021-04-08 15:50:13 +00:00
|
|
|
if let ExprKind::Block(block, _) = body.kind;
|
2021-03-12 14:30:50 +00:00
|
|
|
if !block.stmts.is_empty();
|
|
|
|
then {
|
2022-01-06 15:31:38 +00:00
|
|
|
let mut applicability = Applicability::MachineApplicable;
|
|
|
|
let pat_snip = snippet_with_applicability(cx, pat.span, "..", &mut applicability);
|
|
|
|
let arg_snip = snippet_with_applicability(cx, arg_expression.span, "..", &mut applicability);
|
|
|
|
let mut block_str = snippet_with_applicability(cx, block.span, "..", &mut applicability).into_owned();
|
2021-03-12 14:30:50 +00:00
|
|
|
block_str.remove(0);
|
|
|
|
block_str.pop();
|
2022-01-06 15:31:38 +00:00
|
|
|
let indent = " ".repeat(indent_of(cx, block.stmts[0].span).unwrap_or(0));
|
2021-03-12 14:30:50 +00:00
|
|
|
|
|
|
|
span_lint_and_sugg(
|
|
|
|
cx,
|
|
|
|
SINGLE_ELEMENT_LOOP,
|
2021-10-27 14:48:06 +00:00
|
|
|
expr.span,
|
2021-03-12 14:30:50 +00:00
|
|
|
"for loop over a single element",
|
|
|
|
"try",
|
2022-01-06 15:31:38 +00:00
|
|
|
format!("{{\n{}let {} = &{};{}}}", indent, pat_snip, arg_snip, block_str),
|
|
|
|
applicability,
|
2021-03-12 14:30:50 +00:00
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|