blob: 6d1ee32e5026911a6a0f325606ffd976f52e12e5 [file] [log] [blame] [edit]
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeDef;
use clippy_utils::sym;
use rustc_errors::Applicability;
use rustc_hir as hir;
use rustc_lint::LateContext;
use rustc_span::{Span, Symbol};
use super::ITER_NTH;
pub(super) fn check<'tcx>(
cx: &LateContext<'tcx>,
expr: &hir::Expr<'_>,
iter_recv: &'tcx hir::Expr<'tcx>,
iter_method: Symbol,
iter_span: Span,
nth_span: Span,
) -> bool {
let caller_type = match cx.typeck_results().expr_ty(iter_recv).peel_refs().opt_diag_name(cx) {
Some(sym::Vec) => "`Vec`",
Some(sym::VecDeque) => "`VecDeque`",
_ if cx.typeck_results().expr_ty_adjusted(iter_recv).peel_refs().is_slice() => "slice",
// caller is not a type that we want to lint
_ => return false,
};
span_lint_and_then(
cx,
ITER_NTH,
expr.span,
format!("called `.{iter_method}().nth()` on a {caller_type}"),
|diag| {
let get_method = if iter_method == sym::iter_mut { "get_mut" } else { "get" };
diag.span_suggestion_verbose(
iter_span.to(nth_span),
format!("`{get_method}` is equivalent but more concise"),
get_method,
Applicability::MachineApplicable,
);
},
);
true
}