]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/methods/cloned_instead_of_copied.rs
Fix FN in `iter_cloned_collect` with a large array
[rust.git] / 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};
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 const ITERATOR_COPIED_MSRV: RustcVersion = RustcVersion::new(1, 36, 0);
14 const OPTION_COPIED_MSRV: RustcVersion = RustcVersion::new(1, 35, 0);
15
16 pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span, msrv: Option<&RustcVersion>) {
17     let recv_ty = cx.typeck_results().expr_ty_adjusted(recv);
18     let inner_ty = match recv_ty.kind() {
19         // `Option<T>` -> `T`
20         ty::Adt(adt, subst)
21             if cx.tcx.is_diagnostic_item(sym::option_type, adt.did) && meets_msrv(msrv, &OPTION_COPIED_MSRV) =>
22         {
23             subst.type_at(0)
24         },
25         _ if is_trait_method(cx, expr, sym::Iterator) && meets_msrv(msrv, &ITERATOR_COPIED_MSRV) => {
26             match get_iterator_item_ty(cx, recv_ty) {
27                 // <T as Iterator>::Item
28                 Some(ty) => ty,
29                 _ => return,
30             }
31         },
32         _ => return,
33     };
34     match inner_ty.kind() {
35         // &T where T: Copy
36         ty::Ref(_, ty, _) if is_copy(cx, ty) => {},
37         _ => return,
38     };
39     span_lint_and_sugg(
40         cx,
41         CLONED_INSTEAD_OF_COPIED,
42         span,
43         "used `cloned` where `copied` could be used instead",
44         "try",
45         "copied".into(),
46         Applicability::MachineApplicable,
47     )
48 }