|
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