added new lint implicit_clone
This commit is contained in:
parent
186bf1ccb4
commit
3d3cfd3754
12 changed files with 298 additions and 40 deletions
|
|
@ -769,6 +769,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
&methods::FLAT_MAP_IDENTITY,
|
||||
&methods::FROM_ITER_INSTEAD_OF_COLLECT,
|
||||
&methods::GET_UNWRAP,
|
||||
&methods::IMPLICIT_CLONE,
|
||||
&methods::INEFFICIENT_TO_STRING,
|
||||
&methods::INSPECT_FOR_EACH,
|
||||
&methods::INTO_ITER_ON_REF,
|
||||
|
|
@ -1380,6 +1381,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
LintId::of(&matches::SINGLE_MATCH_ELSE),
|
||||
LintId::of(&methods::FILTER_MAP),
|
||||
LintId::of(&methods::FILTER_MAP_NEXT),
|
||||
LintId::of(&methods::IMPLICIT_CLONE),
|
||||
LintId::of(&methods::INEFFICIENT_TO_STRING),
|
||||
LintId::of(&methods::MAP_FLATTEN),
|
||||
LintId::of(&methods::MAP_UNWRAP_OR),
|
||||
|
|
|
|||
32
clippy_lints/src/methods/implicit_clone.rs
Normal file
32
clippy_lints/src/methods/implicit_clone.rs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
use crate::utils::span_lint_and_sugg;
|
||||
use if_chain::if_chain;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::ExprKind;
|
||||
use rustc_lint::LateContext;
|
||||
use rustc_middle::ty::TyS;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
||||
use super::IMPLICIT_CLONE;
|
||||
use clippy_utils::is_diagnostic_assoc_item;
|
||||
|
||||
pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, trait_diagnostic: Symbol) {
|
||||
if_chain! {
|
||||
if let ExprKind::MethodCall(method_path, _, [arg], _) = &expr.kind;
|
||||
let return_type = cx.typeck_results().expr_ty(&expr);
|
||||
let input_type = cx.typeck_results().expr_ty(arg).peel_refs();
|
||||
if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id);
|
||||
if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did));
|
||||
if TyS::same_type(return_type, input_type);
|
||||
if is_diagnostic_assoc_item(cx, expr_def_id, trait_diagnostic);
|
||||
then {
|
||||
span_lint_and_sugg(
|
||||
cx,IMPLICIT_CLONE,method_path.ident.span,
|
||||
&format!("implicitly cloning a `{}` by calling `{}` on its dereferenced type", ty_name, method_path.ident.name),
|
||||
"consider using",
|
||||
"clone".to_string(),
|
||||
Applicability::MachineApplicable
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
mod bind_instead_of_map;
|
||||
mod bytes_nth;
|
||||
mod filter_map_identity;
|
||||
mod implicit_clone;
|
||||
mod inefficient_to_string;
|
||||
mod inspect_for_each;
|
||||
mod manual_saturating_arithmetic;
|
||||
|
|
@ -1513,6 +1514,32 @@ declare_clippy_lint! {
|
|||
"replace `.bytes().nth()` with `.as_bytes().get()`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Checks for the usage of `_.to_owned()`, `vec.to_vec()`, or similar when calling `_.clone()` would be clearer.
|
||||
///
|
||||
/// **Why is this bad?** These methods do the same thing as `_.clone()` but may be confusing as
|
||||
/// to why we are calling `to_vec` on something that is already a `Vec` or calling `to_owned` on something that is already owned.
|
||||
///
|
||||
/// **Known problems:** None.
|
||||
///
|
||||
/// **Example:**
|
||||
///
|
||||
/// ```rust
|
||||
/// let a = vec![1, 2, 3];
|
||||
/// let b = a.to_vec();
|
||||
/// let c = a.to_owned();
|
||||
/// ```
|
||||
/// Use instead:
|
||||
/// ```rust
|
||||
/// let a = vec![1, 2, 3];
|
||||
/// let b = a.clone();
|
||||
/// let c = a.clone();
|
||||
/// ```
|
||||
pub IMPLICIT_CLONE,
|
||||
pedantic,
|
||||
"implicitly cloning a value by invoking a function on its dereferenced type"
|
||||
}
|
||||
|
||||
pub struct Methods {
|
||||
msrv: Option<RustcVersion>,
|
||||
}
|
||||
|
|
@ -1579,6 +1606,7 @@ impl_lint_pass!(Methods => [
|
|||
MAP_COLLECT_RESULT_UNIT,
|
||||
FROM_ITER_INSTEAD_OF_COLLECT,
|
||||
INSPECT_FOR_EACH,
|
||||
IMPLICIT_CLONE
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for Methods {
|
||||
|
|
@ -1670,6 +1698,10 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
|
|||
["ok_or_else", ..] => unnecessary_lazy_eval::lint(cx, expr, arg_lists[0], "ok_or"),
|
||||
["collect", "map"] => lint_map_collect(cx, expr, arg_lists[1], arg_lists[0]),
|
||||
["for_each", "inspect"] => inspect_for_each::lint(cx, expr, method_spans[1]),
|
||||
["to_owned", ..] => implicit_clone::check(cx, expr, sym::ToOwned),
|
||||
["to_os_string", ..] => implicit_clone::check(cx, expr, sym::OsStr),
|
||||
["to_path_buf", ..] => implicit_clone::check(cx, expr, sym::Path),
|
||||
["to_vec", ..] => implicit_clone::check(cx, expr, sym::slice),
|
||||
_ => {},
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue