about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Wright <mikerite@lavabit.com>2019-08-10 06:01:15 +0200
committerMichael Wright <mikerite@lavabit.com>2019-08-10 06:01:15 +0200
commit77278ccda9f8bfadb81e685255a3411f4287149d (patch)
tree2eb18639df1e93f924becf51fa9c99a136902277
parent170d4861c6d210cb788a7aa00381c54a794f8a14 (diff)
downloadrust-77278ccda9f8bfadb81e685255a3411f4287149d.tar.gz
rust-77278ccda9f8bfadb81e685255a3411f4287149d.zip
Fix `wrong_self_convention` issue
Resolves #4293
-rw-r--r--clippy_lints/src/methods/mod.rs18
-rw-r--r--tests/ui/wrong_self_convention.rs19
2 files changed, 36 insertions, 1 deletions
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index fcf5bbd0ab5..ec8108e3807 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -2547,6 +2547,22 @@ enum SelfKind {
 
 impl SelfKind {
     fn matches<'a>(self, cx: &LateContext<'_, 'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
+        fn matches_value(parent_ty: Ty<'_>, ty: Ty<'_>) -> bool {
+            if ty == parent_ty {
+                true
+            } else if ty.is_box() {
+                ty.boxed_ty() == parent_ty
+            } else if ty.is_rc() || ty.is_arc() {
+                if let ty::Adt(_, substs) = ty.sty {
+                    substs.types().next().map_or(false, |t| t == parent_ty)
+                } else {
+                    false
+                }
+            } else {
+                false
+            }
+        }
+
         fn matches_ref<'a>(
             cx: &LateContext<'_, 'a>,
             mutability: hir::Mutability,
@@ -2567,7 +2583,7 @@ impl SelfKind {
         }
 
         match self {
-            Self::Value => ty == parent_ty,
+            Self::Value => matches_value(parent_ty, ty),
             Self::Ref => {
                 matches_ref(cx, hir::Mutability::MutImmutable, parent_ty, ty) || ty == parent_ty && is_copy(cx, ty)
             },
diff --git a/tests/ui/wrong_self_convention.rs b/tests/ui/wrong_self_convention.rs
index bdffb5af87e..7567fa7158c 100644
--- a/tests/ui/wrong_self_convention.rs
+++ b/tests/ui/wrong_self_convention.rs
@@ -56,3 +56,22 @@ impl Bar {
     fn from_(self) {}
     fn to_mut(&mut self) {}
 }
+
+// Allow Box<Self>, Rc<Self>, Arc<Self> for methods that take conventionally take Self by value
+#[allow(clippy::boxed_local)]
+mod issue4293 {
+    use std::rc::Rc;
+    use std::sync::Arc;
+
+    struct T;
+
+    impl T {
+        fn into_s1(self: Box<Self>) {}
+        fn into_s2(self: Rc<Self>) {}
+        fn into_s3(self: Arc<Self>) {}
+
+        fn into_t1(self: Box<T>) {}
+        fn into_t2(self: Rc<T>) {}
+        fn into_t3(self: Arc<T>) {}
+    }
+}