diff --git a/clippy_lints/src/methods/implicit_clone.rs b/clippy_lints/src/methods/implicit_clone.rs index 90492ffda3cc..0c6d4a41a021 100644 --- a/clippy_lints/src/methods/implicit_clone.rs +++ b/clippy_lints/src/methods/implicit_clone.rs @@ -4,7 +4,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_middle::ty::TyS; +use rustc_middle::ty::{self, TyS}; use rustc_span::{sym, Span}; use super::IMPLICIT_CLONE; @@ -14,7 +14,12 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if is_clone_like(cx, method_name, method_def_id); let return_type = cx.typeck_results().expr_ty(expr); - let input_type = cx.typeck_results().expr_ty(recv).peel_refs(); + let input_type = cx.typeck_results().expr_ty(recv); + // Remove only a single reference. `(&&T)::clone()` returns `&T` + let input_type = match input_type.kind() { + ty::Ref(_, ty, _) => ty, + _ => input_type, + }; 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); then { diff --git a/tests/ui/implicit_clone.rs b/tests/ui/implicit_clone.rs index cef71cf79d79..78c6a2726465 100644 --- a/tests/ui/implicit_clone.rs +++ b/tests/ui/implicit_clone.rs @@ -105,4 +105,10 @@ fn main() { let os_str = OsStr::new("foo"); let _ = os_str.to_owned(); let _ = os_str.to_os_string(); + + // issue #8227 + let pathbuf_ref = &pathbuf; + let pathbuf_ref = &pathbuf_ref; + let _ = pathbuf_ref.to_owned(); + let _ = pathbuf_ref.to_path_buf(); }