Skip to content

Duplicate inherent static methods can be defined in separate impl blocks #22889

Closed
@Byron

Description

@Byron

This code I used to compile fine with a version of Rust that was about 9 days old. All the comments in the code have been there before, now the code fails to compile at the lines assert_eq!(Foo::id(), "FOO"); and assert_eq!(Bar::id(), "BAR");:

#[test]
fn type_aliases() {
    struct Foo {
        a: u32,
    };
    impl Foo {
        fn bark(&self) {
            println!("Wuff {}", self.a);
        }

        fn id() -> &'static str {
            "FOO"
        }
    }
    assert_eq!(Foo::id(), "FOO");
    let f = Foo { a: 1 };
    f.bark();

    type Bar = Foo;
    // assert_eq!(!Bar::id(), "FOO");
    // error: unresolved name `Bar::id`
    // tests/lang.rs:628     assert_eq!(!Bar::id(), "FOO");
    let b = Bar { a: 2 };
    b.bark(); // this works though

    impl Bar {
        // This would add a similarly named implementation, that is difficult to call
        // due to ambiguity.
        // Interestingly, it also affects Foo, as well as Bar !!
        // fn bark(&self) {
        //     println!("Grrrr {}", self.a);
        // }

        fn id() -> &'static str {
            "BAR"
        }   
    }
    // b.bark(); // or f.bark();
    // error: multiple applicable methods in scope [E0034]
    // tests/lang.rs:625     f.bark();
    //                         ^~~~~~
    // tests/lang.rs:615:9: 617:10 note: candidate #1 is defined in an impl for the type `type_aliases::Foo`
    // tests/lang.rs:615         fn bark(&self) {
    // tests/lang.rs:616             println!("Wuff {}", self.a);
    // tests/lang.rs:617         }
    // tests/lang.rs:637:9: 639:10 note: candidate #2 is defined in an impl for the type `type_aliases::Foo`
    // tests/lang.rs:637         fn bark(&self) {
    // tests/lang.rs:638             println!("Grrrr {}", self.a);
    assert_eq!(Bar::id(), "BAR");
}

When compiling this now, I get this error, which seems wrong as Bar affects Foo:

tests/lang.rs:636:16: 636:23 error: multiple applicable methods in scope [E0034]
tests/lang.rs:636     assert_eq!(Foo::id(), "FOO");
                                 ^~~~~~~
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
tests/lang.rs:636:5: 636:34 note: expansion site
tests/lang.rs:632:9: 634:10 note: candidate #1 is defined in an impl for the type `type_aliases::Foo`
tests/lang.rs:632         fn id() -> &'static str {
tests/lang.rs:633             "FOO"
tests/lang.rs:634         }
tests/lang.rs:655:9: 657:10 note: candidate #2 is defined in an impl for the type `type_aliases::Foo`
tests/lang.rs:655         fn id() -> &'static str {
tests/lang.rs:656             "BAR"
tests/lang.rs:657         }
<std macros>:5:10: 5:20 error: the type of this value must be known in this context
<std macros>:5 if ! ( ( * left_val == * right_val ) && ( * right_val == * left_val ) ) {
                        ^~~~~~~~~~
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
tests/lang.rs:636:5: 636:34 note: expansion site
<std macros>:5:24: 5:35 error: the type of this value must be known in this context
<std macros>:5 if ! ( ( * left_val == * right_val ) && ( * right_val == * left_val ) ) {
                                      ^~~~~~~~~~~
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
tests/lang.rs:636:5: 636:34 note: expansion site
tests/lang.rs:670:16: 670:23 error: multiple applicable methods in scope [E0034]
tests/lang.rs:670     assert_eq!(Bar::id(), "BAR");
                                 ^~~~~~~
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
tests/lang.rs:670:5: 670:34 note: expansion site
tests/lang.rs:632:9: 634:10 note: candidate #1 is defined in an impl for the type `type_aliases::Foo`
tests/lang.rs:632         fn id() -> &'static str {
tests/lang.rs:633             "FOO"
tests/lang.rs:634         }
tests/lang.rs:655:9: 657:10 note: candidate #2 is defined in an impl for the type `type_aliases::Foo`
tests/lang.rs:655         fn id() -> &'static str {
tests/lang.rs:656             "BAR"
tests/lang.rs:657         }
<std macros>:5:10: 5:20 error: the type of this value must be known in this context
<std macros>:5 if ! ( ( * left_val == * right_val ) && ( * right_val == * left_val ) ) {
                        ^~~~~~~~~~
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
tests/lang.rs:670:5: 670:34 note: expansion site
<std macros>:5:24: 5:35 error: the type of this value must be known in this context
<std macros>:5 if ! ( ( * left_val == * right_val ) && ( * right_val == * left_val ) ) {
                                      ^~~~~~~~~~~
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
tests/lang.rs:670:5: 670:34 note: expansion site

Even if this is now desired, I think the compiler message could be improved - it looks similar for the two candidates, and if it wasn't for the code shown below it, I would look like it means the same thing.

Meta

$ rustc --verbose --version
rustc 1.0.0-nightly (4db0b3246 2015-02-25) (built 2015-02-25)
binary: rustc
commit-hash: 4db0b32467535d718d6474de7ae8d1007d900818
commit-date: 2015-02-25
build-date: 2015-02-25
host: x86_64-apple-darwin
release: 1.0.0-nightly

Metadata

Metadata

Assignees

Labels

A-trait-systemArea: Trait systemP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language 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