]> git.lizzy.rs Git - rust.git/blobdiff - tests/ui/use_self.fixed
rework use_self impl based on ty::Ty comparison
[rust.git] / tests / ui / use_self.fixed
index 5eae9a7a8069dba541cfe9b18d19e66706efc703..916484eef931f7e12aab8206f1ef113f844ac65a 100644 (file)
@@ -1,8 +1,9 @@
 // run-rustfix
+// edition:2018
 
 #![warn(clippy::use_self)]
 #![allow(dead_code)]
-#![allow(clippy::should_implement_trait)]
+#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms)]
 
 fn main() {}
 
@@ -14,13 +15,14 @@ mod use_self {
             Self {}
         }
         fn test() -> Self {
-            Self::new()
+            Foo::new()
         }
     }
 
     impl Default for Foo {
         fn default() -> Self {
-            Self::new()
+            // FIXME: applicable here
+            Foo::new()
         }
     }
 }
@@ -68,122 +70,9 @@ mod lifetimes {
     }
 }
 
-#[allow(clippy::boxed_local)]
-mod traits {
-
-    use std::ops::Mul;
-
-    trait SelfTrait {
-        fn refs(p1: &Self) -> &Self;
-        fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self;
-        fn mut_refs(p1: &mut Self) -> &mut Self;
-        fn nested(p1: Box<Self>, p2: (&u8, &Self));
-        fn vals(r: Self) -> Self;
-    }
-
-    #[derive(Default)]
-    struct Bad;
-
-    impl SelfTrait for Bad {
-        fn refs(p1: &Self) -> &Self {
-            p1
-        }
-
-        fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
-            p1
-        }
-
-        fn mut_refs(p1: &mut Self) -> &mut Self {
-            p1
-        }
-
-        fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}
-
-        fn vals(_: Self) -> Self {
-            Self::default()
-        }
-    }
-
-    impl Mul for Bad {
-        type Output = Self;
-
-        fn mul(self, rhs: Self) -> Self {
-            rhs
-        }
-    }
-
-    #[derive(Default)]
-    struct Good;
-
-    impl SelfTrait for Good {
-        fn refs(p1: &Self) -> &Self {
-            p1
-        }
-
-        fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
-            p1
-        }
-
-        fn mut_refs(p1: &mut Self) -> &mut Self {
-            p1
-        }
-
-        fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}
-
-        fn vals(_: Self) -> Self {
-            Self::default()
-        }
-    }
-
-    impl Mul for Good {
-        type Output = Self;
-
-        fn mul(self, rhs: Self) -> Self {
-            rhs
-        }
-    }
-
-    trait NameTrait {
-        fn refs(p1: &u8) -> &u8;
-        fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8;
-        fn mut_refs(p1: &mut u8) -> &mut u8;
-        fn nested(p1: Box<u8>, p2: (&u8, &u8));
-        fn vals(p1: u8) -> u8;
-    }
-
-    // Using `Self` instead of the type name is OK
-    impl NameTrait for u8 {
-        fn refs(p1: &Self) -> &Self {
-            p1
-        }
-
-        fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
-            p1
-        }
-
-        fn mut_refs(p1: &mut Self) -> &mut Self {
-            p1
-        }
-
-        fn nested(_p1: Box<Self>, _p2: (&Self, &Self)) {}
-
-        fn vals(_: Self) -> Self {
-            Self::default()
-        }
-    }
-
-    // Check that self arg isn't linted
-    impl Clone for Good {
-        fn clone(&self) -> Self {
-            // Note: Not linted and it wouldn't be valid
-            // because "can't use `Self` as a constructor`"
-            Good
-        }
-    }
-}
-
 mod issue2894 {
     trait IntoBytes {
+        #[allow(clippy::wrong_self_convention)]
         fn into_bytes(&self) -> Vec<u8>;
     }
 
@@ -199,7 +88,11 @@ mod existential {
     struct Foo;
 
     impl Foo {
-        fn bad(foos: &[Self]) -> impl Iterator<Item = &Self> {
+        // FIXME:
+        // TyKind::Def (used for `impl Trait` types) does not include type parameters yet.
+        // See documentation in rustc_hir::hir::TyKind.
+        // The hir tree walk stops at `impl Iterator` level and does not inspect &Foo.
+        fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
             foos.iter()
         }
 
@@ -239,6 +132,7 @@ mod nesting {
     struct Foo {}
     impl Foo {
         fn foo() {
+            #[allow(unused_imports)]
             use self::Foo; // Can't use Self here
             struct Bar {
                 foo: Foo, // Foo != Self
@@ -249,11 +143,23 @@ mod nesting {
                     Self { foo: Foo {} }
                 }
             }
+
+            // Can't use Self here
+            fn baz() -> Foo {
+                Foo {}
+            }
+        }
+
+        // Should lint here
+        fn baz() -> Self {
+            Self {}
         }
     }
 
     enum Enum {
         A,
+        B(u64),
+        C { field: bool },
     }
     impl Enum {
         fn method() {
@@ -261,6 +167,12 @@ mod nesting {
             use self::Enum::*; // Issue 3425
             static STATIC: Enum = Enum::A; // Can't use Self as type
         }
+
+        fn method2() {
+            let _ = Self::B(42);
+            let _ = Self::C { field: true };
+            let _ = Self::A;
+        }
     }
 }
 
@@ -270,11 +182,22 @@ mod issue3410 {
     struct B;
 
     trait Trait<T> {
-        fn a(v: T);
+        fn a(v: T) -> Self;
     }
 
     impl Trait<Vec<A>> for Vec<B> {
-        fn a(_: Vec<A>) {}
+        fn a(_: Vec<A>) -> Self {
+            unimplemented!()
+        }
+    }
+
+    impl<T> Trait<Vec<A>> for Vec<T>
+    where
+        T: Trait<B>,
+    {
+        fn a(v: Vec<A>) -> Self {
+            <Vec<B>>::a(v).into_iter().map(Trait::a).collect()
+        }
     }
 }
 
@@ -290,10 +213,252 @@ mod rustfix {
         fn fun_1() {}
 
         fn fun_2() {
-            Self::fun_1();
-            Self::A;
+            nested::A::fun_1();
+            nested::A::A;
 
             Self {};
         }
     }
 }
+
+mod issue3567 {
+    struct TestStruct {}
+    impl TestStruct {
+        fn from_something() -> Self {
+            Self {}
+        }
+    }
+
+    trait Test {
+        fn test() -> TestStruct;
+    }
+
+    impl Test for TestStruct {
+        fn test() -> TestStruct {
+            // FIXME: applicable here
+            TestStruct::from_something()
+        }
+    }
+}
+
+mod paths_created_by_lowering {
+    use std::ops::Range;
+
+    struct S {}
+
+    impl S {
+        const A: usize = 0;
+        const B: usize = 1;
+
+        // FIXME: applicable here
+        async fn g() -> S {
+            Self {}
+        }
+
+        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
+            // FIXME: applicable here twice
+            &p[S::A..S::B]
+        }
+    }
+
+    trait T {
+        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8];
+    }
+
+    impl T for Range<u8> {
+        fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
+            &p[0..1]
+        }
+    }
+}
+
+// reused from #1997
+mod generics {
+    struct Foo<T> {
+        value: T,
+    }
+
+    impl<T> Foo<T> {
+        // `Self` is applicable here
+        fn foo(value: T) -> Self {
+            Self { value }
+        }
+
+        // `Cannot` use `Self` as a return type as the generic types are different
+        fn bar(value: i32) -> Foo<i32> {
+            Foo { value }
+        }
+    }
+}
+
+mod issue4140 {
+    pub struct Error<From, To> {
+        _from: From,
+        _too: To,
+    }
+
+    pub trait From<T> {
+        type From;
+        type To;
+
+        fn from(value: T) -> Self;
+    }
+
+    pub trait TryFrom<T>
+    where
+        Self: Sized,
+    {
+        type From;
+        type To;
+
+        fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
+    }
+
+    impl<F, T> TryFrom<F> for T
+    where
+        T: From<F>,
+    {
+        type From = Self;
+        type To = Self;
+
+        fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
+            Ok(From::from(value))
+        }
+    }
+
+    impl From<bool> for i64 {
+        type From = bool;
+        type To = Self;
+
+        fn from(value: bool) -> Self {
+            if value {
+                100
+            } else {
+                0
+            }
+        }
+    }
+}
+
+mod issue2843 {
+    trait Foo {
+        type Bar;
+    }
+
+    impl Foo for usize {
+        type Bar = u8;
+    }
+
+    impl<T: Foo> Foo for Option<T> {
+        type Bar = Option<T::Bar>;
+    }
+}
+
+mod issue3859 {
+    pub struct Foo;
+    pub struct Bar([usize; 3]);
+
+    impl Foo {
+        pub const BAR: usize = 3;
+
+        pub fn foo() {
+            const _X: usize = Foo::BAR;
+            // const _Y: usize = Self::BAR;
+        }
+    }
+}
+
+mod issue4305 {
+    trait Foo: 'static {}
+
+    struct Bar;
+
+    impl Foo for Bar {}
+
+    impl<T: Foo> From<T> for Box<dyn Foo> {
+        fn from(t: T) -> Self {
+            // FIXME: applicable here
+            Box::new(t)
+        }
+    }
+}
+
+mod lint_at_item_level {
+    struct Foo {}
+
+    #[allow(clippy::use_self)]
+    impl Foo {
+        fn new() -> Foo {
+            Foo {}
+        }
+    }
+
+    #[allow(clippy::use_self)]
+    impl Default for Foo {
+        fn default() -> Foo {
+            Foo::new()
+        }
+    }
+}
+
+mod lint_at_impl_item_level {
+    struct Foo {}
+
+    impl Foo {
+        #[allow(clippy::use_self)]
+        fn new() -> Foo {
+            Foo {}
+        }
+    }
+
+    impl Default for Foo {
+        #[allow(clippy::use_self)]
+        fn default() -> Foo {
+            Foo::new()
+        }
+    }
+}
+
+mod issue4734 {
+    #[repr(C, packed)]
+    pub struct X {
+        pub x: u32,
+    }
+
+    impl From<X> for u32 {
+        fn from(c: X) -> Self {
+            unsafe { core::mem::transmute(c) }
+        }
+    }
+}
+
+mod nested_paths {
+    use std::convert::Into;
+    mod submod {
+        pub struct B {}
+        pub struct C {}
+
+        impl Into<C> for B {
+            fn into(self) -> C {
+                C {}
+            }
+        }
+    }
+
+    struct A<T> {
+        t: T,
+    }
+
+    impl<T> A<T> {
+        fn new<V: Into<T>>(v: V) -> Self {
+            Self { t: Into::into(v) }
+        }
+    }
+
+    impl A<submod::C> {
+        fn test() -> Self {
+            // FIXME: applicable here
+            A::new::<submod::B>(submod::B {})
+        }
+    }
+}