Skip to content

Commit a24fa49

Browse files
committed
Auto merge of #6179 - flip1995:rewrite_use_self, r=phansch
Rework use_self impl based on ty::Ty comparison #3410 | Take 2 This builds on top of #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 #3410 and Fixes #4143 (same problem) Fixes #2843 Fixes #3859 Fixes #4734 and fixes #6221 Fixes #4305 Fixes #5078 (even at expression level now 🎉) Fixes #3881 and Fixes #4887 (same problem) Fixes #3909 Not yet: #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.
2 parents ab1020b + e107f76 commit a24fa49

8 files changed

+868
-268
lines changed

clippy_lints/src/use_self.rs

+357-191
Large diffs are not rendered by default.

tests/ui/auxiliary/proc_macro_derive.rs

+12
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,15 @@ pub fn derive_foo(_input: TokenStream) -> TokenStream {
4141
}
4242
}
4343
}
44+
45+
#[proc_macro_derive(StructAUseSelf)]
46+
pub fn derive_use_self(_input: TokenStream) -> proc_macro::TokenStream {
47+
quote! {
48+
struct A;
49+
impl A {
50+
fn new() -> A {
51+
A
52+
}
53+
}
54+
}
55+
}

tests/ui/use_self.fixed

+215-9
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
// run-rustfix
22
// edition:2018
3+
// aux-build:proc_macro_derive.rs
34

45
#![warn(clippy::use_self)]
56
#![allow(dead_code)]
6-
#![allow(clippy::should_implement_trait)]
7+
#![allow(clippy::should_implement_trait, clippy::from_over_into)]
8+
9+
#[macro_use]
10+
extern crate proc_macro_derive;
711

812
fn main() {}
913

@@ -71,13 +75,12 @@ mod lifetimes {
7175

7276
mod issue2894 {
7377
trait IntoBytes {
74-
#[allow(clippy::wrong_self_convention)]
75-
fn into_bytes(&self) -> Vec<u8>;
78+
fn to_bytes(&self) -> Vec<u8>;
7679
}
7780

7881
// This should not be linted
7982
impl IntoBytes for u8 {
80-
fn into_bytes(&self) -> Vec<u8> {
83+
fn to_bytes(&self) -> Vec<u8> {
8184
vec![*self]
8285
}
8386
}
@@ -110,17 +113,20 @@ mod tuple_structs {
110113
mod macros {
111114
macro_rules! use_self_expand {
112115
() => {
113-
fn new() -> Self {
114-
Self {}
116+
fn new() -> Foo {
117+
Foo {}
115118
}
116119
};
117120
}
118121

119122
struct Foo {}
120123

121124
impl Foo {
122-
use_self_expand!(); // Should lint in local macros
125+
use_self_expand!(); // Should not lint in local macros
123126
}
127+
128+
#[derive(StructAUseSelf)] // Should not lint in derives
129+
struct A;
124130
}
125131

126132
mod nesting {
@@ -177,11 +183,22 @@ mod issue3410 {
177183
struct B;
178184

179185
trait Trait<T> {
180-
fn a(v: T);
186+
fn a(v: T) -> Self;
181187
}
182188

183189
impl Trait<Vec<A>> for Vec<B> {
184-
fn a(_: Vec<A>) {}
190+
fn a(_: Vec<A>) -> Self {
191+
unimplemented!()
192+
}
193+
}
194+
195+
impl<T> Trait<Vec<A>> for Vec<T>
196+
where
197+
T: Trait<B>,
198+
{
199+
fn a(v: Vec<A>) -> Self {
200+
<Vec<B>>::a(v).into_iter().map(Trait::a).collect()
201+
}
185202
}
186203
}
187204

@@ -252,3 +269,192 @@ mod paths_created_by_lowering {
252269
}
253270
}
254271
}
272+
273+
// reused from #1997
274+
mod generics {
275+
struct Foo<T> {
276+
value: T,
277+
}
278+
279+
impl<T> Foo<T> {
280+
// `Self` is applicable here
281+
fn foo(value: T) -> Self {
282+
Self { value }
283+
}
284+
285+
// `Cannot` use `Self` as a return type as the generic types are different
286+
fn bar(value: i32) -> Foo<i32> {
287+
Foo { value }
288+
}
289+
}
290+
}
291+
292+
mod issue4140 {
293+
pub struct Error<From, To> {
294+
_from: From,
295+
_too: To,
296+
}
297+
298+
pub trait From<T> {
299+
type From;
300+
type To;
301+
302+
fn from(value: T) -> Self;
303+
}
304+
305+
pub trait TryFrom<T>
306+
where
307+
Self: Sized,
308+
{
309+
type From;
310+
type To;
311+
312+
fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
313+
}
314+
315+
impl<F, T> TryFrom<F> for T
316+
where
317+
T: From<F>,
318+
{
319+
type From = Self;
320+
type To = Self;
321+
322+
fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
323+
Ok(From::from(value))
324+
}
325+
}
326+
327+
impl From<bool> for i64 {
328+
type From = bool;
329+
type To = Self;
330+
331+
fn from(value: bool) -> Self {
332+
if value {
333+
100
334+
} else {
335+
0
336+
}
337+
}
338+
}
339+
}
340+
341+
mod issue2843 {
342+
trait Foo {
343+
type Bar;
344+
}
345+
346+
impl Foo for usize {
347+
type Bar = u8;
348+
}
349+
350+
impl<T: Foo> Foo for Option<T> {
351+
type Bar = Option<T::Bar>;
352+
}
353+
}
354+
355+
mod issue3859 {
356+
pub struct Foo;
357+
pub struct Bar([usize; 3]);
358+
359+
impl Foo {
360+
pub const BAR: usize = 3;
361+
362+
pub fn foo() {
363+
const _X: usize = Foo::BAR;
364+
// const _Y: usize = Self::BAR;
365+
}
366+
}
367+
}
368+
369+
mod issue4305 {
370+
trait Foo: 'static {}
371+
372+
struct Bar;
373+
374+
impl Foo for Bar {}
375+
376+
impl<T: Foo> From<T> for Box<dyn Foo> {
377+
fn from(t: T) -> Self {
378+
Box::new(t)
379+
}
380+
}
381+
}
382+
383+
mod lint_at_item_level {
384+
struct Foo {}
385+
386+
#[allow(clippy::use_self)]
387+
impl Foo {
388+
fn new() -> Foo {
389+
Foo {}
390+
}
391+
}
392+
393+
#[allow(clippy::use_self)]
394+
impl Default for Foo {
395+
fn default() -> Foo {
396+
Foo::new()
397+
}
398+
}
399+
}
400+
401+
mod lint_at_impl_item_level {
402+
struct Foo {}
403+
404+
impl Foo {
405+
#[allow(clippy::use_self)]
406+
fn new() -> Foo {
407+
Foo {}
408+
}
409+
}
410+
411+
impl Default for Foo {
412+
#[allow(clippy::use_self)]
413+
fn default() -> Foo {
414+
Foo::new()
415+
}
416+
}
417+
}
418+
419+
mod issue4734 {
420+
#[repr(C, packed)]
421+
pub struct X {
422+
pub x: u32,
423+
}
424+
425+
impl From<X> for u32 {
426+
fn from(c: X) -> Self {
427+
unsafe { core::mem::transmute(c) }
428+
}
429+
}
430+
}
431+
432+
mod nested_paths {
433+
use std::convert::Into;
434+
mod submod {
435+
pub struct B {}
436+
pub struct C {}
437+
438+
impl Into<C> for B {
439+
fn into(self) -> C {
440+
C {}
441+
}
442+
}
443+
}
444+
445+
struct A<T> {
446+
t: T,
447+
}
448+
449+
impl<T> A<T> {
450+
fn new<V: Into<T>>(v: V) -> Self {
451+
Self { t: Into::into(v) }
452+
}
453+
}
454+
455+
impl A<submod::C> {
456+
fn test() -> Self {
457+
Self::new::<submod::B>(submod::B {})
458+
}
459+
}
460+
}

0 commit comments

Comments
 (0)