From 83ae5edd50bf81810821fa9ceaf256036305aed9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 9 Jan 2024 17:31:59 +0100 Subject: [PATCH] Don't lint with `map_clone` if current type is `Option` or `Result` and method call is `as_ref`. --- clippy_lints/src/methods/map_clone.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs index 527e557987d..19eea00d545 100644 --- a/clippy_lints/src/methods/map_clone.rs +++ b/clippy_lints/src/methods/map_clone.rs @@ -15,22 +15,29 @@ use rustc_span::{sym, Span}; use super::MAP_CLONE; -fn should_run_lint(cx: &LateContext<'_>, method_id: DefId) -> bool { +fn should_run_lint(cx: &LateContext<'_>, e: &hir::Expr<'_>, method_id: DefId) -> bool { if is_diag_trait_item(cx, method_id, sym::Iterator) { return true; } if !cx.tcx.impl_of_method(method_id).map_or(false, |id| { - is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Option) - || is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Result) + let identity = cx.tcx.type_of(id).instantiate_identity(); + is_type_diagnostic_item(cx, identity, sym::Option) || is_type_diagnostic_item(cx, identity, sym::Result) }) { return false; } + // We check if the previous method call is `as_ref`. + if let hir::ExprKind::MethodCall(path1, receiver, _, _) = &e.kind + && let hir::ExprKind::MethodCall(path2, _, _, _) = &receiver.kind + { + return path2.ident.name != sym::as_ref || path1.ident.name != sym::map; + } + return true; } pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_>, arg: &hir::Expr<'_>, msrv: &Msrv) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) - && should_run_lint(cx, method_id) + && should_run_lint(cx, e, method_id) { match arg.kind { hir::ExprKind::Closure(&hir::Closure { body, .. }) => {