]> git.lizzy.rs Git - rust.git/blobdiff - tests/ui/use_self.rs
Auto merge of #3603 - xfix:random-state-lint, r=phansch
[rust.git] / tests / ui / use_self.rs
index 40cef1a9362af3c9b9a85b181eb5a501ff256117..b201e160ebd93e2ac2555372f82442c84afd60f2 100644 (file)
@@ -1,8 +1,15 @@
-#![feature(plugin)]
-#![plugin(clippy)]
-#![warn(use_self)]
-#![allow(dead_code)]
+// Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
+#![warn(clippy::use_self)]
+#![allow(dead_code)]
+#![allow(clippy::should_implement_trait)]
 
 fn main() {}
 
@@ -43,3 +50,203 @@ fn default() -> Self {
         }
     }
 }
+
+mod lifetimes {
+    struct Foo<'a> {
+        foo_str: &'a str,
+    }
+
+    impl<'a> Foo<'a> {
+        // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->
+        // Foo<'b>`
+        fn foo(s: &str) -> Foo {
+            Foo { foo_str: s }
+        }
+        // cannot replace with `Self`, because that's `Foo<'a>`
+        fn bar() -> Foo<'static> {
+            Foo { foo_str: "foo" }
+        }
+
+        // FIXME: the lint does not handle lifetimed struct
+        // `Self` should be applicable here
+        fn clone(&self) -> Foo<'a> {
+            Foo { foo_str: self.foo_str }
+        }
+    }
+}
+
+#[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: &Bad) -> &Bad {
+            p1
+        }
+
+        fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {
+            p1
+        }
+
+        fn mut_refs(p1: &mut Bad) -> &mut Bad {
+            p1
+        }
+
+        fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}
+
+        fn vals(_: Bad) -> Bad {
+            Bad::default()
+        }
+    }
+
+    impl Mul for Bad {
+        type Output = Bad;
+
+        fn mul(self, rhs: Bad) -> Bad {
+            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 {
+        fn into_bytes(&self) -> Vec<u8>;
+    }
+
+    // This should not be linted
+    impl IntoBytes for u8 {
+        fn into_bytes(&self) -> Vec<u8> {
+            vec![*self]
+        }
+    }
+}
+
+mod existential {
+    struct Foo;
+
+    impl Foo {
+        fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
+            foos.iter()
+        }
+
+        fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {
+            foos.iter()
+        }
+    }
+}
+
+mod tuple_structs {
+    pub struct TS(i32);
+
+    impl TS {
+        pub fn ts() -> Self {
+            TS(0)
+        }
+    }
+}
+
+mod issue3410 {
+
+    struct A;
+    struct B;
+
+    trait Trait<T> {
+        fn a(v: T);
+    }
+
+    impl Trait<Vec<A>> for Vec<B> {
+        fn a(_: Vec<A>) {}
+    }
+}
+
+mod issue3425 {
+    enum Enum {
+        A,
+    }
+    impl Enum {
+        fn a() {
+            use self::Enum::*;
+        }
+    }
+}