Skip to content

Commit

Permalink
Auto merge of rust-lang#6179 - flip1995:rewrite_use_self, r=phansch
Browse files Browse the repository at this point in the history
Rework use_self impl based on ty::Ty comparison rust-lang#3410 | Take 2

This builds on top of rust-lang#5531

I already reviewed and approved the commits by `@montrivo.` So only the review of my commits should be necessary.

I would also appreciate your review `@montrivo,` since you are familiar with the challenges here.

Fixes rust-lang#3410 and Fixes rust-lang#4143 (same problem)
Fixes rust-lang#2843
Fixes rust-lang#3859
Fixes rust-lang#4734 and fixes rust-lang#6221
Fixes rust-lang#4305
Fixes rust-lang#5078 (even at expression level now 🎉)
Fixes rust-lang#3881 and Fixes rust-lang#4887 (same problem)
Fixes rust-lang#3909

Not yet: rust-lang#4140 (test added)

All the credit for the fixes goes to `@montrivo.` I only refactored and copy and pasted his code.

changelog: rewrite [`use_self`] lint and fix multiple (8) FPs. One to go.
  • Loading branch information
bors committed Feb 12, 2021
2 parents fa2c1d6 + 52f98d8 commit 605e9ba
Show file tree
Hide file tree
Showing 8 changed files with 880 additions and 271 deletions.
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

0 comments on commit 605e9ba

Please sign in to comment.