Add cloned_instead_of_copied lint
This commit is contained in:
parent
1e0a3ff55c
commit
0462666c70
8 changed files with 151 additions and 1 deletions
|
|
@ -759,6 +759,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
methods::BYTES_NTH,
|
||||
methods::CHARS_LAST_CMP,
|
||||
methods::CHARS_NEXT_CMP,
|
||||
methods::CLONED_INSTEAD_OF_COPIED,
|
||||
methods::CLONE_DOUBLE_REF,
|
||||
methods::CLONE_ON_COPY,
|
||||
methods::CLONE_ON_REF_PTR,
|
||||
|
|
@ -1380,6 +1381,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
|
||||
LintId::of(matches::MATCH_WILD_ERR_ARM),
|
||||
LintId::of(matches::SINGLE_MATCH_ELSE),
|
||||
LintId::of(methods::CLONED_INSTEAD_OF_COPIED),
|
||||
LintId::of(methods::FILTER_MAP_NEXT),
|
||||
LintId::of(methods::IMPLICIT_CLONE),
|
||||
LintId::of(methods::INEFFICIENT_TO_STRING),
|
||||
|
|
|
|||
38
clippy_lints/src/methods/cloned_instead_of_copied.rs
Normal file
38
clippy_lints/src/methods/cloned_instead_of_copied.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::is_trait_method;
|
||||
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::{sym, Span};
|
||||
|
||||
use super::CLONED_INSTEAD_OF_COPIED;
|
||||
|
||||
pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span) {
|
||||
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_type, adt.did) => subst.type_at(0),
|
||||
_ if is_trait_method(cx, expr, sym::Iterator) => 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,
|
||||
)
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ mod chars_next_cmp;
|
|||
mod chars_next_cmp_with_unwrap;
|
||||
mod clone_on_copy;
|
||||
mod clone_on_ref_ptr;
|
||||
mod cloned_instead_of_copied;
|
||||
mod expect_fun_call;
|
||||
mod expect_used;
|
||||
mod filetype_is_file;
|
||||
|
|
@ -73,6 +74,29 @@ use rustc_span::symbol::SymbolStr;
|
|||
use rustc_span::{sym, Span};
|
||||
use rustc_typeck::hir_ty_to_ty;
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for usages of `cloned()` on an `Iterator` or `Option` where
|
||||
/// `copied()` could be used instead.
|
||||
///
|
||||
/// **Why is this bad?** `copied()` is better because it guarantees that the type being cloned
|
||||
/// implements `Copy`.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// [1, 2, 3].iter().cloned();
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// [1, 2, 3].iter().copied();
|
||||
/// ```
|
||||
pub CLONED_INSTEAD_OF_COPIED,
|
||||
pedantic,
|
||||
"used `cloned` where `copied` could be used instead"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for `.unwrap()` calls on `Option`s and on `Result`s.
|
||||
///
|
||||
|
|
@ -1638,6 +1662,7 @@ impl_lint_pass!(Methods => [
|
|||
CLONE_ON_COPY,
|
||||
CLONE_ON_REF_PTR,
|
||||
CLONE_DOUBLE_REF,
|
||||
CLONED_INSTEAD_OF_COPIED,
|
||||
INEFFICIENT_TO_STRING,
|
||||
NEW_RET_NO_SELF,
|
||||
SINGLE_CHAR_PATTERN,
|
||||
|
|
@ -1909,6 +1934,7 @@ fn check_methods<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, msrv: Optio
|
|||
("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
|
||||
("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
|
||||
("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
|
||||
("cloned", []) => cloned_instead_of_copied::check(cx, expr, recv, span),
|
||||
("collect", []) => match method_call!(recv) {
|
||||
Some(("cloned", [recv2], _)) => iter_cloned_collect::check(cx, expr, recv2),
|
||||
Some(("map", [m_recv, m_arg], _)) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue