Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework use_self impl based on ty::Ty comparison #3410 | Take 2 #6179

Merged
merged 8 commits into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
563 changes: 369 additions & 194 deletions clippy_lints/src/use_self.rs

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions tests/ui/auxiliary/proc_macro_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,15 @@ pub fn derive_foo(_input: TokenStream) -> TokenStream {
}
}
}

#[proc_macro_derive(StructAUseSelf)]
pub fn derive_use_self(_input: TokenStream) -> proc_macro::TokenStream {
quote! {
struct A;
impl A {
fn new() -> A {
A
}
}
}
}
224 changes: 215 additions & 9 deletions tests/ui/use_self.fixed
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
// 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)]

#[macro_use]
extern crate proc_macro_derive;

fn main() {}

Expand Down Expand Up @@ -71,13 +75,12 @@ mod lifetimes {

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> {
fn to_bytes(&self) -> Vec<u8> {
vec![*self]
}
}
Expand Down Expand Up @@ -110,17 +113,20 @@ mod tuple_structs {
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 {
Expand Down Expand Up @@ -177,11 +183,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()
}
}
}

Expand Down Expand Up @@ -252,3 +269,192 @@ mod paths_created_by_lowering {
}
}
}

// 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 {})
}
}
}
Loading