blob: d80d6f7810f537ec181feb785fafd041cf0aca83 [file]
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::res::{MaybeDef, MaybeTypeckRes};
use clippy_utils::ty::{get_iterator_item_ty, is_copy};
use rustc_errors::Applicability;
use rustc_hir::Expr;
use rustc_lint::LateContext;
use rustc_middle::ty;
use rustc_span::{Span, sym};
use super::CLONED_INSTEAD_OF_COPIED;
pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Msrv) {
let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
let inner_ty = match recv_ty.kind() {
// `Option<T>` -> `T`
ty::Adt(adt, subst)
if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && msrv.meets(cx, msrvs::OPTION_COPIED) =>
{
subst.type_at(0)
},
_ if cx.ty_based_def(expr).opt_parent(cx).is_diag_item(cx, sym::Iterator)
&& msrv.meets(cx, msrvs::ITERATOR_COPIED) =>
{
match get_iterator_item_ty(cx, recv_ty) {
// <T as Iterator>::Item
Some(ty) => ty,
_ => return,
}
},
_ => return,
};
match inner_ty.kind() {
// &T where T: Copy
ty::Ref(_, ty, _) if is_copy(cx, *ty) => {},
_ => return,
}
span_lint_and_sugg(
cx,
CLONED_INSTEAD_OF_COPIED,
span,
"used `cloned` where `copied` could be used instead",
"try",
"copied".into(),
Applicability::MachineApplicable,
);
}