diff options
Diffstat (limited to 'clippy_lints/src/methods/implicit_clone.rs')
| -rw-r--r-- | clippy_lints/src/methods/implicit_clone.rs | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/clippy_lints/src/methods/implicit_clone.rs b/clippy_lints/src/methods/implicit_clone.rs index 1211e2f2bf7..81c42de145f 100644 --- a/clippy_lints/src/methods/implicit_clone.rs +++ b/clippy_lints/src/methods/implicit_clone.rs @@ -1,28 +1,36 @@ use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::{is_diag_item_method, is_diag_trait_item}; 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 rustc_span::{sym, Span}; use super::IMPLICIT_CLONE; -use clippy_utils::is_diagnostic_assoc_item; -pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, trait_diagnostic: Symbol) { +pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, span: Span) { if_chain! { - if let ExprKind::MethodCall(method_path, _, [arg], _) = &expr.kind; + if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); + if match method_name { + "to_os_string" => is_diag_item_method(cx, method_def_id, sym::OsStr), + "to_owned" => is_diag_trait_item(cx, method_def_id, sym::ToOwned), + "to_path_buf" => is_diag_item_method(cx, method_def_id, sym::Path), + "to_vec" => cx.tcx.impl_of_method(method_def_id) + .map(|impl_did| Some(impl_did) == cx.tcx.lang_items().slice_alloc_impl()) + == Some(true), + _ => false, + }; 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); + let input_type = cx.typeck_results().expr_ty(recv).peel_refs(); 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), + cx, + IMPLICIT_CLONE, + span, + &format!("implicitly cloning a `{}` by calling `{}` on its dereferenced type", ty_name, method_name), "consider using", "clone".to_string(), Applicability::MachineApplicable |
