about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-06 21:26:46 +0000
committerbors <bors@rust-lang.org>2022-07-06 21:26:46 +0000
commitafb34eb261aa8e54b9045a582d2553bb7d6fd463 (patch)
tree1ad16265c543c740c1f369dfe315ed46a649972a
parentf93d418f1789a5782053e99038db7d6701c8a30c (diff)
parent988b813649c147383bcce125c9afbb0adc681110 (diff)
downloadrust-afb34eb261aa8e54b9045a582d2553bb7d6fd463.tar.gz
rust-afb34eb261aa8e54b9045a582d2553bb7d6fd463.zip
Auto merge of #9096 - Jarcho:needless_borrow_subs, r=Manishearth
Fix `needless_borrow` 9095

fixes #9095
changelog: Don't lint `needless_borrow` on method receivers when it would change which trait impl is called
-rw-r--r--clippy_lints/src/dereference.rs11
-rw-r--r--tests/ui/needless_borrow.fixed12
-rw-r--r--tests/ui/needless_borrow.rs12
3 files changed, 32 insertions, 3 deletions
diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs
index 1be1b862066..6dddb969f33 100644
--- a/clippy_lints/src/dereference.rs
+++ b/clippy_lints/src/dereference.rs
@@ -772,9 +772,14 @@ fn walk_parents<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (Position, &
                             } else if let Some(trait_id) = cx.tcx.trait_of_item(id)
                                 && let arg_ty = cx.tcx.erase_regions(cx.typeck_results().expr_ty_adjusted(e))
                                 && let ty::Ref(_, sub_ty, _) = *arg_ty.kind()
-                                && let subs = cx.typeck_results().node_substs_opt(child_id).unwrap_or_else(
-                                    || cx.tcx.mk_substs([].iter())
-                                ) && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
+                                && let subs = match cx
+                                    .typeck_results()
+                                    .node_substs_opt(parent.hir_id)
+                                    .and_then(|subs| subs.get(1..))
+                                {
+                                    Some(subs) => cx.tcx.mk_substs(subs.iter().copied()),
+                                    None => cx.tcx.mk_substs([].iter()),
+                                } && let impl_ty = if cx.tcx.fn_sig(id).skip_binder().inputs()[0].is_ref() {
                                     // Trait methods taking `&self`
                                     sub_ty
                                 } else {
diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed
index cb005122436..09afe2ddbbf 100644
--- a/tests/ui/needless_borrow.fixed
+++ b/tests/ui/needless_borrow.fixed
@@ -115,6 +115,18 @@ fn main() {
         fn foo_ref(&self) {}
     }
     (&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`
+
+    struct S;
+    impl From<S> for u32 {
+        fn from(s: S) -> Self {
+            (&s).into()
+        }
+    }
+    impl From<&S> for u32 {
+        fn from(s: &S) -> Self {
+            0
+        }
+    }
 }
 
 #[allow(clippy::needless_borrowed_reference)]
diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs
index d636a401003..3ae4722a1f8 100644
--- a/tests/ui/needless_borrow.rs
+++ b/tests/ui/needless_borrow.rs
@@ -115,6 +115,18 @@ fn main() {
         fn foo_ref(&self) {}
     }
     (&&()).foo_ref(); // Don't lint. `&()` will call `<() as FooRef>::foo_ref`
+
+    struct S;
+    impl From<S> for u32 {
+        fn from(s: S) -> Self {
+            (&s).into()
+        }
+    }
+    impl From<&S> for u32 {
+        fn from(s: &S) -> Self {
+            0
+        }
+    }
 }
 
 #[allow(clippy::needless_borrowed_reference)]