]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/methods/cloned_instead_of_copied.rs
Merge commit 'fdb84cbfd25908df5683f8f62388f663d9260e39' into clippyup
[rust.git] / src / tools / clippy / clippy_lints / src / methods / cloned_instead_of_copied.rs
1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::ty::{get_iterator_item_ty, is_copy};
3 use clippy_utils::{is_trait_method, meets_msrv, msrvs};
4 use rustc_errors::Applicability;
5 use rustc_hir::Expr;
6 use rustc_lint::LateContext;
7 use rustc_middle::ty;
8 use rustc_semver::RustcVersion;
9 use rustc_span::{sym, Span};
10
11 use super::CLONED_INSTEAD_OF_COPIED;
12
13 pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Option<RustcVersion>) {
14     let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
15     let inner_ty = match recv_ty.kind() {
16         // `Option<T>` -> `T`
17         ty::Adt(adt, subst)
18             if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) && meets_msrv(msrv, msrvs::OPTION_COPIED) =>
19         {
20             subst.type_at(0)
21         },
22         _ if is_trait_method(cx, expr, sym::Iterator) && meets_msrv(msrv, msrvs::ITERATOR_COPIED) => {
23             match get_iterator_item_ty(cx, recv_ty) {
24                 // <T as Iterator>::Item
25                 Some(ty) => ty,
26                 _ => return,
27             }
28         },
29         _ => return,
30     };
31     match inner_ty.kind() {
32         // &T where T: Copy
33         ty::Ref(_, ty, _) if is_copy(cx, *ty) => {},
34         _ => return,
35     };
36     span_lint_and_sugg(
37         cx,
38         CLONED_INSTEAD_OF_COPIED,
39         span,
40         "used `cloned` where `copied` could be used instead",
41         "try",
42         "copied".into(),
43         Applicability::MachineApplicable,
44     );
45 }