|
1 | 1 | use clippy_utils::diagnostics::span_lint_and_sugg; |
| 2 | +use clippy_utils::{is_diag_item_method, is_diag_trait_item}; |
2 | 3 | use if_chain::if_chain; |
3 | 4 | use rustc_errors::Applicability; |
4 | 5 | use rustc_hir as hir; |
5 | | -use rustc_hir::ExprKind; |
6 | 6 | use rustc_lint::LateContext; |
7 | 7 | use rustc_middle::ty::TyS; |
8 | | -use rustc_span::symbol::Symbol; |
| 8 | +use rustc_span::{sym, Span}; |
9 | 9 |
|
10 | 10 | use super::IMPLICIT_CLONE; |
11 | | -use clippy_utils::is_diagnostic_assoc_item; |
12 | 11 |
|
13 | | -pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, trait_diagnostic: Symbol) { |
| 12 | +pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, span: Span) { |
14 | 13 | if_chain! { |
15 | | - if let ExprKind::MethodCall(method_path, _, [arg], _) = &expr.kind; |
| 14 | + if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); |
| 15 | + if match method_name { |
| 16 | + "to_os_string" => is_diag_item_method(cx, method_def_id, sym::OsStr), |
| 17 | + "to_owned" => is_diag_trait_item(cx, method_def_id, sym::ToOwned), |
| 18 | + "to_path_buf" => is_diag_item_method(cx, method_def_id, sym::Path), |
| 19 | + "to_vec" => cx.tcx.impl_of_method(method_def_id) |
| 20 | + .map(|impl_did| Some(impl_did) == cx.tcx.lang_items().slice_alloc_impl()) |
| 21 | + == Some(true), |
| 22 | + _ => false, |
| 23 | + }; |
16 | 24 | let return_type = cx.typeck_results().expr_ty(expr); |
17 | | - let input_type = cx.typeck_results().expr_ty(arg).peel_refs(); |
18 | | - if let Some(expr_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); |
| 25 | + let input_type = cx.typeck_results().expr_ty(recv).peel_refs(); |
19 | 26 | if let Some(ty_name) = input_type.ty_adt_def().map(|adt_def| cx.tcx.item_name(adt_def.did)); |
20 | 27 | if TyS::same_type(return_type, input_type); |
21 | | - if is_diagnostic_assoc_item(cx, expr_def_id, trait_diagnostic); |
22 | 28 | then { |
23 | 29 | span_lint_and_sugg( |
24 | | - cx,IMPLICIT_CLONE,method_path.ident.span, |
25 | | - &format!("implicitly cloning a `{}` by calling `{}` on its dereferenced type", ty_name, method_path.ident.name), |
| 30 | + cx, |
| 31 | + IMPLICIT_CLONE, |
| 32 | + span, |
| 33 | + &format!("implicitly cloning a `{}` by calling `{}` on its dereferenced type", ty_name, method_name), |
26 | 34 | "consider using", |
27 | 35 | "clone".to_string(), |
28 | 36 | Applicability::MachineApplicable |
|
0 commit comments