about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/methods/useless_asref.rs19
-rw-r--r--tests/ui/useless_asref.fixed5
-rw-r--r--tests/ui/useless_asref.rs5
3 files changed, 23 insertions, 6 deletions
diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs
index 82313257e5c..6d3da42775f 100644
--- a/clippy_lints/src/methods/useless_asref.rs
+++ b/clippy_lints/src/methods/useless_asref.rs
@@ -55,12 +55,19 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
         let (base_res_ty, res_depth) = walk_ptrs_ty_depth(res_ty);
         let (base_rcv_ty, rcv_depth) = walk_ptrs_ty_depth(rcv_ty);
         if base_rcv_ty == base_res_ty && rcv_depth >= res_depth {
-            // allow the `as_ref` or `as_mut` if it is followed by another method call
-            if let Some(parent) = get_parent_expr(cx, expr)
-                && let hir::ExprKind::MethodCall(segment, ..) = parent.kind
-                && segment.ident.span != expr.span
-            {
-                return;
+            if let Some(parent) = get_parent_expr(cx, expr) {
+                // allow the `as_ref` or `as_mut` if it is followed by another method call
+                if let hir::ExprKind::MethodCall(segment, ..) = parent.kind
+                    && segment.ident.span != expr.span
+                {
+                    return;
+                }
+
+                // allow the `as_ref` or `as_mut` if they belong to a closure that changes
+                // the number of references
+                if matches!(parent.kind, hir::ExprKind::Closure(..)) && rcv_depth != res_depth {
+                    return;
+                }
             }
 
             let mut applicability = Applicability::MachineApplicable;
diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed
index ddbb9255b46..2f179200bb3 100644
--- a/tests/ui/useless_asref.fixed
+++ b/tests/ui/useless_asref.fixed
@@ -198,6 +198,11 @@ fn issue_12528() {
     let _ = opt.as_ref().map(RcWeak::clone);
 }
 
+fn issue_14088() {
+    let s = Some("foo");
+    let _: Option<&str> = s.as_ref().map(|x| x.as_ref());
+}
+
 fn main() {
     not_ok();
     ok();
diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs
index b0405e930a2..9851a0caac4 100644
--- a/tests/ui/useless_asref.rs
+++ b/tests/ui/useless_asref.rs
@@ -198,6 +198,11 @@ fn issue_12528() {
     let _ = opt.as_ref().map(RcWeak::clone);
 }
 
+fn issue_14088() {
+    let s = Some("foo");
+    let _: Option<&str> = s.as_ref().map(|x| x.as_ref());
+}
+
 fn main() {
     not_ok();
     ok();