Skip to content

Wrong messages from compiler confusing methods with the same name from different traits #143740

Open
@AlexanderSerbul

Description

@AlexanderSerbul

I tried this code:

fn main() {

    println!("Overloading");
    
    #[derive(Debug)]
    struct Container {
        val: String
    };
    
    trait AName {
        fn name(&self) -> String;
    }
    
    trait BName {
        fn name(&self) -> String;
    }

    impl AName for Container {
        fn name(&self) -> String {
            "aname".into()
        }
    }

    impl BName for Container {
        fn name(&self) -> String {
            "bname".into()
        }
    }

    //

    #[derive(Debug)]
    struct Container2 {
        val: String
    };
    
    trait AName2 {
        fn name(&self) -> String;
    }
    
    trait BName2 {
        fn name(&self, v: bool) -> String;
    }

    impl AName2 for Container2 {
        fn name(&self) -> String {
            "aname2".into()
        }
    }

    impl BName2 for Container2 {
        fn name(&self, v: bool) -> String {
            "bname2".into()
        }
    }    
    
    let c2 = Container2 { val: "abc".into() };
    println!("c2 = {:?}", c2.name());
}

I expected to see this happen: useful message about error from compiler.

Instead, this happened:

error[E0034]: multiple applicable items in scope
  --> src/main.rs:59:30
   |
59 |     println!("c2 = {:?}", c2.name());
   |                              ^^^^ multiple `name` found
   |
note: candidate #1 is defined in the trait `AName`
  --> src/main.rs:12:9
   |
12 |         fn name(&self) -> String;
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in the trait `BName`
  --> src/main.rs:16:9
   |
16 |         fn name(&self) -> String;
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #3 is defined in an impl of the trait `AName2` for the type `Container2`
  --> src/main.rs:47:9
   |
47 |         fn name(&self) -> String {
   |         ^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #4 is defined in an impl of the trait `BName2` for the type `Container2`
  --> src/main.rs:53:9
   |
53 |         fn name(&self, v: bool) -> String {
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

As you see, there are only two candidates with "name" for Container2 struct only (from AName2 and from BName2), not four.

help: disambiguate the method for candidate #1
   |
59 -     println!("c2 = {:?}", c2.name());
59 +     println!("c2 = {:?}", AName::name(&c2));
   |
help: disambiguate the method for candidate #2
   |
59 -     println!("c2 = {:?}", c2.name());
59 +     println!("c2 = {:?}", BName::name(&c2));
   |
help: disambiguate the method for candidate #3
   |
59 -     println!("c2 = {:?}", c2.name());
59 +     println!("c2 = {:?}", AName2::name(&c2));
   |
help: disambiguate the method for candidate #4
   |
59 -     println!("c2 = {:?}", c2.name());
59 +     println!("c2 = {:?}", BName2::name(&c2));
   |

There are wrong messages from a compiler about suggesting using not implemented traits "AName" and "BName" with c2. But as you see c2 has only traits AName2 and BName2 implemented. And signature of using "BName2::name" is wrong (2 args are needed, not one).

Meta

rustc --version --verbose:

1.88.0 stable from rust playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-method-lookupArea: Method lookup (typeck, post `rustc_resolve`, not to be confused with `A-resolve`)D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions