blob: 484d00e94f45083b61fad79d41e61ea5d6a853a9 [file]
use crate::methods::utils::derefs_to_slice;
use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::res::MaybeDef;
use clippy_utils::ty::get_iterator_item_ty;
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::{Symbol, sym};
use super::ITER_CLONED_COLLECT;
pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, method_name: Symbol, expr: &Expr<'_>, recv: &'tcx Expr<'_>) {
let expr_ty = cx.typeck_results().expr_ty(expr);
if let ty::Adt(def, args) = expr_ty.kind()
&& def.is_diag_item(cx, sym::Vec)
&& let recv_ty = cx.typeck_results().expr_ty(recv)
&& let Some(slice) = derefs_to_slice(cx, recv, recv_ty)
&& let Some(iter_item_ty) = get_iterator_item_ty(cx, recv_ty)
&& let ty::Ref(_, iter_item_ty, _) = iter_item_ty.kind()
&& *iter_item_ty == args.type_at(0)
&& let Some(to_replace) = expr.span.trim_start(slice.span.source_callsite())
{
span_lint_and_then(
cx,
ITER_CLONED_COLLECT,
to_replace,
format!("called `.iter().{method_name}().collect()` on a slice to create a `Vec`"),
|diag| {
diag.span_suggestion_verbose(
to_replace,
"calling `.to_vec()` is both faster and more readable",
".to_vec()",
Applicability::MachineApplicable,
);
},
);
}
}