// run-rustfix
+// edition:2018
+// aux-build:proc_macro_derive.rs
#![warn(clippy::use_self)]
#![allow(dead_code)]
-#![allow(clippy::should_implement_trait)]
+#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms, clippy::from_over_into)]
+
+#[macro_use]
+extern crate proc_macro_derive;
fn main() {}
}
}
-#[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 {
- fn into_bytes(&self) -> Vec<u8>;
+ fn to_bytes(&self) -> Vec<u8>;
}
// This should not be linted
impl IntoBytes for u8 {
- fn into_bytes(&self) -> Vec<u8> {
+ fn to_bytes(&self) -> Vec<u8> {
vec![*self]
}
}
mod macros {
macro_rules! use_self_expand {
() => {
- fn new() -> Self {
- Self {}
+ fn new() -> Foo {
+ Foo {}
}
};
}
struct Foo {}
impl Foo {
- use_self_expand!(); // Should lint in local macros
+ use_self_expand!(); // Should not lint in local macros
}
+
+ #[derive(StructAUseSelf)] // Should not lint in derives
+ struct A;
}
mod nesting {
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()
+ }
}
}
}
}
}
+
+mod issue3567 {
+ struct TestStruct {}
+ impl TestStruct {
+ fn from_something() -> Self {
+ Self {}
+ }
+ }
+
+ trait Test {
+ fn test() -> TestStruct;
+ }
+
+ impl Test for TestStruct {
+ fn test() -> TestStruct {
+ Self::from_something()
+ }
+ }
+}
+
+mod paths_created_by_lowering {
+ use std::ops::Range;
+
+ struct S {}
+
+ impl S {
+ const A: usize = 0;
+ const B: usize = 1;
+
+ async fn g() -> Self {
+ Self {}
+ }
+
+ fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
+ &p[Self::A..Self::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 {
+ 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 {
+ Self::new::<submod::B>(submod::B {})
+ }
+ }
+}