// run-rustfix
-// edition:2018
+// aux-build:proc_macro_derive.rs
#![warn(clippy::use_self)]
#![allow(dead_code)]
-#![allow(clippy::should_implement_trait, clippy::upper_case_acronyms)]
+#![allow(
+ clippy::should_implement_trait,
+ clippy::upper_case_acronyms,
+ clippy::from_over_into,
+ clippy::self_named_constructors
+)]
+
+#[macro_use]
+extern crate proc_macro_derive;
fn main() {}
mod issue2894 {
trait IntoBytes {
- #[allow(clippy::wrong_self_convention)]
- 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> {
- vec![*self]
+ 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()
+ }
}
}
}
}
}
+
+// 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>>;
+ }
+
+ // FIXME: Suggested fix results in infinite recursion.
+ // impl<F, T> TryFrom<F> for T
+ // where
+ // T: From<F>,
+ // {
+ // type From = Self::From;
+ // type To = Self::To;
+
+ // 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 {})
+ }
+ }
+}
+
+mod issue6818 {
+ #[derive(serde::Deserialize)]
+ struct A {
+ a: i32,
+ }
+}
+
+mod issue7206 {
+ struct MyStruct<const C: char>;
+ impl From<MyStruct<'a'>> for MyStruct<'b'> {
+ fn from(_s: MyStruct<'a'>) -> Self {
+ Self
+ }
+ }
+
+ // keep linting non-`Const` generic args
+ struct S<'a> {
+ inner: &'a str,
+ }
+
+ struct S2<T> {
+ inner: T,
+ }
+
+ impl<T> S2<T> {
+ fn new() -> Self {
+ unimplemented!();
+ }
+ }
+
+ impl<'a> S2<S<'a>> {
+ fn new_again() -> Self {
+ Self::new()
+ }
+ }
+}
+
+mod self_is_ty_param {
+ trait Trait {
+ type Type;
+ type Hi;
+
+ fn test();
+ }
+
+ impl<I> Trait for I
+ where
+ I: Iterator,
+ I::Item: Trait, // changing this to Self would require <Self as Iterator>
+ {
+ type Type = I;
+ type Hi = I::Item;
+
+ fn test() {
+ let _: I::Item;
+ let _: I; // this could lint, but is questionable
+ }
+ }
+}