Skip to content

False positive with use_self and generics #3410

Closed
@daboross

Description

@daboross

As far as I can tell, the use_self is incorrectly ignoring generic parameters when implementing traits for some types with generics.

Here's my example:

pub trait PhaseTransform<T>: Sized {
    fn transform_from(v: T) -> Self;
}

pub struct IntermediatePhase;

pub struct FinalPhase;

impl PhaseTransform<Vec<IntermediatePhase>> for Vec<FinalPhase> {
    fn transform_from(_: Vec<IntermediatePhase>) -> Self {
        unimplemented!()
    }
}

impl<T> PhaseTransform<Vec<IntermediatePhase>> for Vec<T>
where
    T: PhaseTransform<FinalPhase>,
{
    fn transform_from(intermediates: Vec<IntermediatePhase>) -> Self {
        <Vec<FinalPhase>>::transform_from(intermediates)
            .into_iter()
            .map(PhaseTransform::transform_from)
            .collect()
    }
}

This, as far as I can tell, uses Self as much as possible. But with -W clippy::pedantic, clippy warns of three more places where it thinks I should be able to use Self:

$ cargo clippy -- -W clippy::pedantic
    Checking clippy-false-positive-test v0.1.0 (/home/daboross/clippy-false-positive-test)                                              
warning: unnecessary structure name repetition                                                                                          
  --> src/lib.rs:10:26                                                                                                                  
   |                                                                                                                                    
10 |     fn transform_from(_: Vec<IntermediatePhase>) -> Self {                                                                         
   |                          ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`                                           
   |                                                                                                                                    
   = note: `-W clippy::use-self` implied by `-W clippy::pedantic`                                                                       
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#use_self                   
                                                                                                                                        
warning: unnecessary structure name repetition                                                                                          
  --> src/lib.rs:19:38                                                                                                                  
   |                                                                                                                                    
19 |     fn transform_from(intermediates: Vec<IntermediatePhase>) -> Self {                                                             
   |                                      ^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`                               
   |                                                                                                                                    
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#use_self                   
                                                                                                                                        
warning: unnecessary structure name repetition                                                                                          
  --> src/lib.rs:20:10                                                                                                                  
   |                                                                                                                                    
20 |         <Vec<FinalPhase>>::transform_from(intermediates)                                                                           
   |          ^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`                                                                  
   |                                                                                                                                    
   = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.212/index.html#use_self                   
                                                                                                                                        
    Finished dev [unoptimized + debuginfo] target(s) in 0.21s

There are two mistakes: it's treating Vec<IntermediatePhase> as Vec<FinalPhase>, and it's treating Vec<FinalPhase> as Vec<T>.

Hope the example is minimal enough - my original trigger was with a custom trait like this, and it seemed hard to come up with any other reasonable use case which caused this situation.

Clippy version:

$ cargo clippy -V                    
clippy 0.0.212 (b1d0343 2018-10-19)

Related to #1993.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions